The current anatomy of a good movie: Can we do better?
Ever since the “Golden Age” of cinema in the 1930s that marked silent film a thing of the past, the film industry has witnessed unparalleled success and growth. From the first technicolor movies like The Wizard of Oz and Gone With The Wind to the computationally animated The Matrix, Jurassic Park, and the first fully computer-animated film, Toy Story, the industry of motion pictures has contributed greatly not only to technology but also the global economy. Especially in the current challenging economy and there has been a sharp decline in theater audience—[shrinking by half in the last 4 years]https://en.wikipedia.org/wiki/IMDb), film distributors are hesitant to take on a movie unless they can see its success first hand. Therefore, box-office, or the entire earnings generated through movie ticket sales, has been recognized as one of the primary indicators to compare film success. Many rely on it to decide whether to both produce and watch a film. However, are high grossing movies actually… good? If so, what else can we use to measure them?
One of the popular other indicators used worldwide to assess a movie is IMDb rating (or International Movie Database). IMDb rating allows 83 million of its registered users to cast a vote (from 1 to 10) on every released title in the database. These votes are then aggregated and summarized as a single IMDb rating visible on IMDb.com. Accessible to anyone, anywhere, these ratings are a simplified way to see what people all over the world think about movies and have been an often-used indicator for a film’s popularity/quality. This led us to wonder: How do the most profitable movies rank on the IMDb website?
From our visualization above, the top 20 grossing films have a range of scores from 6.2 to 8.4 stars. Conversely, the top 20 scored movies on IMDb globally grossed between 28,419,159 and 1,120,210,896 U.S. Dollars. When comparing the IMDbscore and amount of money grossed, we can observe that there isn’t much of a relationship between the rating of a film (or how “objectively good” a movie is) and the amount of money it makes.
On the other hand, to investigate opinions of films from professionals and trusted members of the film industry, we can turn to the Academy Awards.

It seems like a movie’s revenue is not a strong indicator for its accolades. Among the top 20 movies with the highest worldwide box office and their Oscars awards, only 11 movies had any nominations at all. Furthermore, this list gets even more narrowed down as we look into wins/loses. Titanic, Avatar, Black Panther, and Frozen are the only movies in the top 20 highest worldwide grossing movies to have had at least one nomination and won, with Titanic as the most prolific with 11 out of 14 categories (after grouping some of them together).
The Oscars, however, are not an objective means of awardship. In 2015, the academy “awarded all 20 acting nominations to white actors for the first of two consecutive years, inspiring April Reign to create the hashtag #OscarsSoWhite” (Ugwu, 2020). Leaving the determination of film success to the Academy seems to yield a celebration of white creators and artists, excluding a whole world of diverse cinema.

As of 2020, almost half of the U.S. population (42.2%) are people of color. Yet, Hollywood fails to consider them when making movies. In the top 20 highest grossing movies of all time, only 2 movies featured a non-white main character—both of which were Black males. None of these movies are in the top 5 of this list in terms of profit and grossing while other underrepresented demographics (Latines, East/South/Southeast Asians, Native Americans, Afro Latinos, etc.) are left completely off the screen.
Furthermore, in the history of the Oscars only three women have won the coveted best director title. This reflects a gendered measure of success within the film industry, where most of the praise goes to films about and created by cis men. To measure the representation of women in films, we can turn to the Bechdel test which was popularized by Alison Bechdel. The test names three simple criteria: (1) it has to have at least two women in it, who (2) who talk to each other, about (3) something besides a man. Although this test seems easy enough, only 25% of the top scored films and 50% of the top grossing films passed. Interestingly enough, when comparing the two datasets to an average Bechdel test score breakdown, we can see that the highest grossing films all have women and an above average score of “ok” and “dubious”. However, the highest scored films have less than average “ok” and dubious” scores.
The trend we have identified here is strong: movies that make the most money are most often than not white-, male-, and Euro-centric. Even looking beyond the dollar, we can see how scoring systems and awards are biased towards this demographic as well. Although the American movie industry continues achieved commercial success, it historically has, and continues to, lack sufficient representation. While Hollywood has undoubtedly created notable films like The Wizard of Oz, Gone With The Wind, The Matrix, and Jurassic Park, the industry’s focus on white males has resulted in a significant loss of diverse perspectives and cinematic experiences. It seems like when we are trying to judge a movie, we should have a broader repertoire of measurements for how good it is other than just money.
Code Appendix
library(tidyverse)
library(splitstackshape)
library(dbplyr)
library(stringr)
library(readr)
library(ggplot2)
library(ggthemes)
library(fivethirtyeight)
library(highcharter)
library(scales)
library(rvest)
library(scales)
library(plotly)
library(gapminder)
library(forcats)
library(magrittr)
#Loading raw data
box_office <-read_csv("All Time Worldwide Box Office.csv")
movies_info <- read_csv("movies.csv")
oscars_award <- read_csv("the_oscar_award.csv")
bechdel <- data.frame(bechdel)
bechdelset <- read_csv("bechdelset.csv")
Bechdelmoney <- read_csv("Bechdelmoney.csv")
biopics <- data.frame(biopics)
RatingGross <- read_csv("RatingGross_edit2.csv")
#Data cleaning for figure 1
#average grossing for each top 20 scored
top_score <- movies_info %>%
select(name, score, year, gross) %>%
arrange(desc(score))
#average grossing for each top 20 scored
low_score <- movies_info %>%
select(name, score, year, gross) %>%
arrange(score)
oscarwins <- movies_info %>%
filter(name %in% c("The Lord of the Rings: The Return of the King", "Titanic", "Ben-Hur", "West Side Story", "The English Patient", "The Last Emperor", "Gigi", "Slumdog Millionaire", "Amadeus", "Gandhi")) %>%
summarize(sum=sum(gross))
movies_info %>%
group_by(year) %>%
summarize(total_movies = n(),
american_movies = sum(country == "United States"),
percent_american = 100 * american_movies / total_movies)
doubledata <- movies_info %>%
left_join(RatingGross,
by = c("name", "year" = "Year"))
topgross <- doubledata %>%
filter(doubledata$Rank < 25) %>%
arrange(desc(`WorldwideBox Office`)) %>%
select(name, score.x, Rank, `WorldwideBox Office`)
duplicate_rows <- topgross[duplicated(topgross), ]
topgross <- unique(topgross)
toprate <- doubledata %>%
select(name, score.x, Rank, `WorldwideBox Office`) %>%
arrange(desc(score.x))
topgross_20 <- head(topgross, n = 20) %>%
select(name, score.x, `WorldwideBox Office`)
topscore_20 <- head(toprate, n = 20) %>%
select(name, score.x, `WorldwideBox Office`)
#Data cleaning for figure 2
# Changing Box Office variables into numerical values
box_office <-box_office %>%
mutate(`WorldwideBox Office`=as.numeric(str_replace_all(`WorldwideBox Office`,"[$,]",""))) %>%
mutate(`DomesticBox Office`=as.numeric(str_replace_all(`DomesticBox Office`,"[$,]",""))) %>%
mutate(`InternationalBox Office`=as.numeric(str_replace_all(`InternationalBox Office`,"[$,]","")))
#Getting the Top 20 Box Office
box_office_top20 <- box_office %>%
arrange(Rank) %>%
head(20) %>%
mutate(Movie=ifelse(Movie=="Harry Potter and the Deathly Hallows:…", "Harry Potter and the Deathly Hallows: Part 2",Movie))
#Creating Oscar category data frame
oscars_category <- tibble(
levels(factor(oscars_award$category)))
oscars_category <- oscars_category %>%
rename("category"="levels(factor(oscars_award$category))")
oscars_category <- oscars_category %>%
mutate(broad_category=word(category,1)) %>%
mutate(broad_category=
case_when(broad_category =="ART" ~"ART DIRECTION",
broad_category == "BEST" ~ "BEST PICTURE",
broad_category == "FILM" ~ "FILM EDITING",
broad_category == "ACTOR" | broad_category=="ACTRESS" ~ "ACTING",
TRUE ~ broad_category)
)
#Top 20 Box Office Movies and awards dataset by joining dataframes
box_office_top20_awards <- box_office_top20 %>%
inner_join(oscars_award,by=c("Movie"="film")) %>%
filter(Year == year_film) %>%
inner_join(oscars_category)
box_office_top20_awards <- box_office_top20_awards %>% group_by(Movie,year_film) %>%
summarize(total=n()) %>% inner_join(oscars_award,by=c("Movie"="film")) %>%
filter(year_film.x == year_film.y) %>%
inner_join(oscars_category) %>%
select(Movie, year_film.x,total,year_ceremony,name,winner,broad_category)
#Data cleaning for figure 3
#Changing movie names so they match across movies_info and box_office_top20
movies_info <- movies_info %>% mutate(name=case_when(
name=="Star Wars: Episode VII - The Force Awakens" ~ "Star Wars Ep. VII: The Force Awakens",
name =="Star Wars: Episode VIII - The Last Jedi" ~ "Star Wars Ep. VIII: The Last Jedi",
TRUE~name)) %>%
mutate(company=case_when(
company=="Walt Disney Animation Studios" | company=="Walt Disney Pictures" ~"Walt Disney",
TRUE~company))
#Joinining movies_info and box_office_top20
box_office_top20_info<- box_office_top20 %>%
inner_join(movies_info,by=c("Movie"="name","Year"="year"))
#Making top20 main character's race data frame
top20_race <- data.frame(star=box_office_top20_info$star,Race=c("White","White","White","White","White","White","Black","White","White","White","White","Black","White","White","White","White","White","White","White","White"))
#Joining box_office_top20_info with top20_race dataframe
box_office_top20_info <- box_office_top20_info %>% data.frame(top20_race) %>% select(!star.1)
#Data cleaning for figure 4
bechdelset <- bechdelset %>%
mutate(set_factor = factor(set))
bechdelsetav <- bechdelset %>%
group_by(set_factor, clean_test) %>%
summarize(count = n ())
bechdelsetav <- bechdelsetav %>%
mutate(percent = count/ 20 * 100)
bechdelav <- bechdel %>%
group_by(clean_test) %>%
summarize (count = n ())
bechdelav <- bechdelav %>%
mutate(percent = round(count/ 1794 * 100)) %>%
mutate(set_factor = "Average Bechdel Scores")
jointav <- rbind(bechdelsetav, bechdelav)
jointav$clean_test <- factor(jointav$clean_test, levels = c("nowomen", "notalk", "men", "dubious", "ok"))
#Figure 1
colors <- c("#AC2528", "#E4792C", "#764484", "#346491", "#448746")
fig1<-plot_ly(bechdelset, x = ~score.x, y = ~`WorldwideBox Office`, color = ~clean_test, colors = colors, type = 'scatter', mode = 'markers',
hoverinfo = 'text',
text = ~paste('</br>', name,
'</br>', "IMDB Score:", score.x,
'</br>', "Worldwide Grossing:", comma(`WorldwideBox Office`))) %>%
layout(title = 'IMDB Score vs. Amount of Money Grossed',
xaxis = list(title = 'IMDB Score'),
yaxis = list(title = 'Worldwide Box Office'),
legend = list(title = list(text = "Bechdel Test Score"),
titles = list(topgross_20 = "Top 20 Grossing", topscore_20 = "Top 20 Scored")))
#Figure 2
fig2<-box_office_top20_awards %>%
ggplot(aes(x = fct_reorder(Movie, total,.fun=sum),alpha=winner,fill=fct_reorder(broad_category,winner))) +
geom_bar()+
theme_classic() +
theme(legend.position = "right")+
scale_fill_viridis_d()+
coord_flip()+
labs(y="Total Nominations",x="Movie",title="Top 20 Movies with Highest Worldwide Box Office vs Oscars Awards",subtitle = "By Category and Wins",fill="Category",alpha="Winner")+
theme(plot.title = element_text(face="bold",size=16),plot.subtitle = element_text(size=14),axis.title.x = element_text(size=14),axis.text.x = element_text(size=12),axis.title.y = element_text(size=14),axis.text.y = element_text(size=12))
#Figure 3
fig3<-box_office_top20_info %>%
mutate(Profit=gross-budget) %>%
ggplot(aes(x=budget,y=gross,color=Race,size=Profit)) +
geom_point()+
theme_minimal()+
scale_x_continuous(labels = label_comma())+
scale_y_continuous(labels = label_comma())+
scale_size_continuous(labels = label_comma())+
scale_color_viridis_d(option="E")+
labs(y="Total Gross",x="Budget",title="Top 20 Movies with Highest Worldwide Box Office",subtitle = "By Profit and Race of Main Character")+
theme(plot.title = element_text(face="bold",size=12),plot.subtitle = element_text(size=10),axis.text.x = element_text(size=8))+
annotate("text",x=200000000,y=1430000000,label="Black Panther",size=3,color="red3")+
annotate("text",x=260000000,y=1750000000,label="The Lion King (2019)",size=3,color="red3")
#Figure 4
fig4<-hchart(jointav, "column", hcaes(x = set_factor, y = count, group = clean_test), stacking = "percent") %>%
hc_title(text = "Bechdel Test Scores") %>%
hc_colors(colors) %>%
hc_tooltip(pointFormat = "{series.name}: {point.percentage:.1f}%") %>%
hc_yAxis(title = "Percentage", labels = list(format = '{value}%')) %>%
hc_xAxis(title = NULL) %>%
hc_colors(colors) %>%
hc_legend(enabled = TRUE)
LS0tCnRpdGxlOiAiTWVhc3VyaW5nIGEgTW92aWXigJlzIFN1Y2Nlc3MgQmV5b25kIHRoZSBEb2xsYXI6IDxicj4gQXJlIFRoZSBIaWdoZXN0IEdyb3NzaW5nIE1vdmllcyBvZiBBbGwgVGltZXMgQWN0dWFsbHnigKZHb29kPyIKYXV0aG9yOiAiRW1tYSBNYWxjb2xtLCBOYSBOZ3V5ZW4iCmRhdGU6ICIyMDIzLTA0LTExIgpvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgc3BsaXRfYnk6IE5PTkUKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDoKICAgICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KPCEtLS0gQmVnaW4gc3R5bGluZyBjb2RlLiAtLS0+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Ci8qIFdob2xlIGRvY3VtZW50OiAqLwpib2R5ewogIGZvbnQtZmFtaWx5OiAiUGFsYXRpbm8gTGlub3R5cGUiLCAiQm9vayBBbnRpcXVhIiwgUGFsYXRpbm8sIHNlcmlmOwogIGZvbnQtc2l6ZTogMTJwdDsKfQpoMS50aXRsZSB7CiAgZm9udC1zaXplOiAzOHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoNC5hdXRob3IgewogIGZvbnQtc2l6ZTogMThweDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KaDQuZGF0ZSB7CiAgZm9udC1zaXplOiAxOHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQo8L3N0eWxlPgo8IS0tLSBFbmQgc3R5bGluZyBjb2RlLiAtLS0+CgpgYGB7cixlY2hvPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgdGlkeSA9IFRSVUUpCmBgYAoKCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3BsaXRzdGFja3NoYXBlKQpsaWJyYXJ5KGRicGx5cikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkoZml2ZXRoaXJ0eWVpZ2h0KQpsaWJyYXJ5KGhpZ2hjaGFydGVyKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShydmVzdCkKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdhcG1pbmRlcikKbGlicmFyeShmb3JjYXRzKQpsaWJyYXJ5KG1hZ3JpdHRyKQoKCiNMb2FkaW5nIHJhdyBkYXRhCmJveF9vZmZpY2UgPC1yZWFkX2NzdigiQWxsIFRpbWUgV29ybGR3aWRlIEJveCBPZmZpY2UuY3N2IikKbW92aWVzX2luZm8gPC0gcmVhZF9jc3YoIm1vdmllcy5jc3YiKQpvc2NhcnNfYXdhcmQgPC0gcmVhZF9jc3YoInRoZV9vc2Nhcl9hd2FyZC5jc3YiKQpiZWNoZGVsIDwtIGRhdGEuZnJhbWUoYmVjaGRlbCkKYmVjaGRlbHNldCA8LSByZWFkX2NzdigiYmVjaGRlbHNldC5jc3YiKQpCZWNoZGVsbW9uZXkgPC0gcmVhZF9jc3YoIkJlY2hkZWxtb25leS5jc3YiKQpiaW9waWNzIDwtIGRhdGEuZnJhbWUoYmlvcGljcykKUmF0aW5nR3Jvc3MgPC0gcmVhZF9jc3YoIlJhdGluZ0dyb3NzX2VkaXQyLmNzdiIpCgpgYGAKCmBgYHtyLGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNEYXRhIGNsZWFuaW5nIGZvciBmaWd1cmUgMQojYXZlcmFnZSBncm9zc2luZyBmb3IgZWFjaCB0b3AgMjAgc2NvcmVkCgp0b3Bfc2NvcmUgPC0gbW92aWVzX2luZm8gJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZSwgeWVhciwgZ3Jvc3MpICU+JSAKICBhcnJhbmdlKGRlc2Moc2NvcmUpKQoKI2F2ZXJhZ2UgZ3Jvc3NpbmcgZm9yIGVhY2ggdG9wIDIwIHNjb3JlZAoKbG93X3Njb3JlIDwtIG1vdmllc19pbmZvICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUsIHllYXIsIGdyb3NzKSAlPiUgCiAgYXJyYW5nZShzY29yZSkKCgpvc2NhcndpbnMgPC0gIG1vdmllc19pbmZvICU+JSAKICBmaWx0ZXIobmFtZSAlaW4lIGMoIlRoZSBMb3JkIG9mIHRoZSBSaW5nczogVGhlIFJldHVybiBvZiB0aGUgS2luZyIsICJUaXRhbmljIiwgIkJlbi1IdXIiLCAiV2VzdCBTaWRlIFN0b3J5IiwgIlRoZSBFbmdsaXNoIFBhdGllbnQiLCAiVGhlIExhc3QgRW1wZXJvciIsICJHaWdpIiwgIlNsdW1kb2cgTWlsbGlvbmFpcmUiLCAiQW1hZGV1cyIsICJHYW5kaGkiKSkgJT4lIAogc3VtbWFyaXplKHN1bT1zdW0oZ3Jvc3MpKQoKCmRvdWJsZWRhdGEgPC0gbW92aWVzX2luZm8gJT4lCiAgbGVmdF9qb2luKFJhdGluZ0dyb3NzLAogICAgYnkgPSBjKCJuYW1lIiwgInllYXIiID0gIlllYXIiKSkKCgp0b3Bncm9zcyA8LSBkb3VibGVkYXRhICU+JSAKICBmaWx0ZXIoZG91YmxlZGF0YSRSYW5rIDwgMjUpICU+JSAgCiAgYXJyYW5nZShkZXNjKGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkpICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgUmFuaywgYFdvcmxkd2lkZUJveCBPZmZpY2VgKQoKZHVwbGljYXRlX3Jvd3MgPC0gdG9wZ3Jvc3NbZHVwbGljYXRlZCh0b3Bncm9zcyksIF0KdG9wZ3Jvc3MgPC0gdW5pcXVlKHRvcGdyb3NzKQoKCnRvcHJhdGUgPC0gZG91YmxlZGF0YSAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLngsIFJhbmssIGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkgJT4lIAogIGFycmFuZ2UoZGVzYyhzY29yZS54KSkgCgogICAgIAp0b3Bncm9zc18yMCA8LSBoZWFkKHRvcGdyb3NzLCBuID0gMjApICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgYFdvcmxkd2lkZUJveCBPZmZpY2VgKQp0b3BzY29yZV8yMCA8LSBoZWFkKHRvcHJhdGUsIG4gPSAyMCkgJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZS54LCBgV29ybGR3aWRlQm94IE9mZmljZWApCgoKCmBgYAoKYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0RhdGEgY2xlYW5pbmcgZm9yIGZpZ3VyZSAyCiMgQ2hhbmdpbmcgQm94IE9mZmljZSB2YXJpYWJsZXMgaW50byBudW1lcmljYWwgdmFsdWVzCmJveF9vZmZpY2UgPC1ib3hfb2ZmaWNlICU+JSAKIG11dGF0ZShgV29ybGR3aWRlQm94IE9mZmljZWA9YXMubnVtZXJpYyhzdHJfcmVwbGFjZV9hbGwoYFdvcmxkd2lkZUJveCBPZmZpY2VgLCJbJCxdIiwiIikpKSAlPiUgCiAgbXV0YXRlKGBEb21lc3RpY0JveCBPZmZpY2VgPWFzLm51bWVyaWMoc3RyX3JlcGxhY2VfYWxsKGBEb21lc3RpY0JveCBPZmZpY2VgLCJbJCxdIiwiIikpKSAlPiUKICBtdXRhdGUoYEludGVybmF0aW9uYWxCb3ggT2ZmaWNlYD1hcy5udW1lcmljKHN0cl9yZXBsYWNlX2FsbChgSW50ZXJuYXRpb25hbEJveCBPZmZpY2VgLCJbJCxdIiwiIikpKQoKI0dldHRpbmcgdGhlIFRvcCAyMCBCb3ggT2ZmaWNlCmJveF9vZmZpY2VfdG9wMjAgPC0gYm94X29mZmljZSAlPiUgIAogIGFycmFuZ2UoUmFuaykgJT4lIAogIGhlYWQoMjApICU+JSAKICBtdXRhdGUoTW92aWU9aWZlbHNlKE1vdmllPT0iSGFycnkgUG90dGVyIGFuZCB0aGUgRGVhdGhseSBIYWxsb3dzOuKApiIsICJIYXJyeSBQb3R0ZXIgYW5kIHRoZSBEZWF0aGx5IEhhbGxvd3M6IFBhcnQgMiIsTW92aWUpKQoKCiNDcmVhdGluZyBPc2NhciBjYXRlZ29yeSBkYXRhIGZyYW1lCm9zY2Fyc19jYXRlZ29yeSA8LSB0aWJibGUoCmxldmVscyhmYWN0b3Iob3NjYXJzX2F3YXJkJGNhdGVnb3J5KSkpCiAgCgpvc2NhcnNfY2F0ZWdvcnkgPC0gb3NjYXJzX2NhdGVnb3J5ICU+JSAKICByZW5hbWUoImNhdGVnb3J5Ij0ibGV2ZWxzKGZhY3Rvcihvc2NhcnNfYXdhcmQkY2F0ZWdvcnkpKSIpIAogIAoKb3NjYXJzX2NhdGVnb3J5IDwtIG9zY2Fyc19jYXRlZ29yeSAlPiUgCiAgbXV0YXRlKGJyb2FkX2NhdGVnb3J5PXdvcmQoY2F0ZWdvcnksMSkpICU+JSAKICBtdXRhdGUoYnJvYWRfY2F0ZWdvcnk9CiAgICAgICAgICAgY2FzZV93aGVuKGJyb2FkX2NhdGVnb3J5ID09IkFSVCIgfiJBUlQgRElSRUNUSU9OIiwKICAgICAgICAgICAgICAgICAgICAgYnJvYWRfY2F0ZWdvcnkgPT0gIkJFU1QiIH4gIkJFU1QgUElDVFVSRSIsCiAgICAgICAgICAgICAgICAgICAgIGJyb2FkX2NhdGVnb3J5ID09ICJGSUxNIiB+ICJGSUxNIEVESVRJTkciLAogICAgICAgICAgICAgICAgICAgICBicm9hZF9jYXRlZ29yeSA9PSAiQUNUT1IiIHwgYnJvYWRfY2F0ZWdvcnk9PSJBQ1RSRVNTIiB+ICJBQ1RJTkciLAogICAgICAgICAgICAgICAgICAgIFRSVUUgfiBicm9hZF9jYXRlZ29yeSkKICAgICAgICAgICAgKSAKCiNUb3AgMjAgQm94IE9mZmljZSBNb3ZpZXMgYW5kIGF3YXJkcyBkYXRhc2V0IGJ5IGpvaW5pbmcgZGF0YWZyYW1lcwpib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyA8LSBib3hfb2ZmaWNlX3RvcDIwICU+JSAKICBpbm5lcl9qb2luKG9zY2Fyc19hd2FyZCxieT1jKCJNb3ZpZSI9ImZpbG0iKSkgJT4lIAogIGZpbHRlcihZZWFyID09IHllYXJfZmlsbSkgJT4lIAogIGlubmVyX2pvaW4ob3NjYXJzX2NhdGVnb3J5KSAgCgpib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyA8LSBib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyAlPiUgZ3JvdXBfYnkoTW92aWUseWVhcl9maWxtKSAlPiUgCiAgc3VtbWFyaXplKHRvdGFsPW4oKSkgJT4lICBpbm5lcl9qb2luKG9zY2Fyc19hd2FyZCxieT1jKCJNb3ZpZSI9ImZpbG0iKSkgJT4lIAogIGZpbHRlcih5ZWFyX2ZpbG0ueCA9PSB5ZWFyX2ZpbG0ueSkgJT4lIAogIGlubmVyX2pvaW4ob3NjYXJzX2NhdGVnb3J5KSAgJT4lIAogIHNlbGVjdChNb3ZpZSwgeWVhcl9maWxtLngsdG90YWwseWVhcl9jZXJlbW9ueSxuYW1lLHdpbm5lcixicm9hZF9jYXRlZ29yeSkKYGBgCgpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDMKI0NoYW5naW5nIG1vdmllIG5hbWVzIHNvIHRoZXkgbWF0Y2ggYWNyb3NzIG1vdmllc19pbmZvIGFuZCBib3hfb2ZmaWNlX3RvcDIwCgptb3ZpZXNfaW5mbyA8LSBtb3ZpZXNfaW5mbyAlPiUgIG11dGF0ZShuYW1lPWNhc2Vfd2hlbigKICBuYW1lPT0iU3RhciBXYXJzOiBFcGlzb2RlIFZJSSAtIFRoZSBGb3JjZSBBd2FrZW5zIiB+ICJTdGFyIFdhcnMgRXAuIFZJSTogVGhlIEZvcmNlIEF3YWtlbnMiLAogIG5hbWUgPT0iU3RhciBXYXJzOiBFcGlzb2RlIFZJSUkgLSBUaGUgTGFzdCBKZWRpIiB+ICJTdGFyIFdhcnMgRXAuIFZJSUk6IFRoZSBMYXN0IEplZGkiLApUUlVFfm5hbWUpKSAlPiUgCiAgbXV0YXRlKGNvbXBhbnk9Y2FzZV93aGVuKAogICAgY29tcGFueT09IldhbHQgRGlzbmV5IEFuaW1hdGlvbiBTdHVkaW9zIiB8IGNvbXBhbnk9PSJXYWx0IERpc25leSBQaWN0dXJlcyIgfiJXYWx0IERpc25leSIsClRSVUV+Y29tcGFueSkpCgojSm9pbmluaW5nIG1vdmllc19pbmZvIGFuZCBib3hfb2ZmaWNlX3RvcDIwCgpib3hfb2ZmaWNlX3RvcDIwX2luZm88LSBib3hfb2ZmaWNlX3RvcDIwICU+JQogIGlubmVyX2pvaW4obW92aWVzX2luZm8sYnk9YygiTW92aWUiPSJuYW1lIiwiWWVhciI9InllYXIiKSkKCiNNYWtpbmcgdG9wMjAgbWFpbiBjaGFyYWN0ZXIncyByYWNlIGRhdGEgZnJhbWUKdG9wMjBfcmFjZSA8LSBkYXRhLmZyYW1lKHN0YXI9Ym94X29mZmljZV90b3AyMF9pbmZvJHN0YXIsUmFjZT1jKCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJCbGFjayIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiQmxhY2siLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIikpCgojSm9pbmluZyBib3hfb2ZmaWNlX3RvcDIwX2luZm8gd2l0aCB0b3AyMF9yYWNlIGRhdGFmcmFtZQpib3hfb2ZmaWNlX3RvcDIwX2luZm8gPC0gYm94X29mZmljZV90b3AyMF9pbmZvICU+JSBkYXRhLmZyYW1lKHRvcDIwX3JhY2UpICU+JSBzZWxlY3QoIXN0YXIuMSkKCmBgYAoKYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0RhdGEgY2xlYW5pbmcgZm9yIGZpZ3VyZSA0CgpiZWNoZGVsc2V0IDwtIGJlY2hkZWxzZXQgJT4lIAogIG11dGF0ZShzZXRfZmFjdG9yID0gZmFjdG9yKHNldCkpIAoKYmVjaGRlbHNldGF2IDwtIGJlY2hkZWxzZXQgJT4lIAogIGdyb3VwX2J5KHNldF9mYWN0b3IsIGNsZWFuX3Rlc3QpICU+JSAKICBzdW1tYXJpemUoY291bnQgPSBuICgpKQoKYmVjaGRlbHNldGF2IDwtIGJlY2hkZWxzZXRhdiAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC8gMjAgKiAxMDApCgpiZWNoZGVsYXYgPC0gYmVjaGRlbCAlPiUgCiAgZ3JvdXBfYnkoY2xlYW5fdGVzdCkgJT4lICAKICBzdW1tYXJpemUgKGNvdW50ID0gbiAoKSkKCmJlY2hkZWxhdiA8LSBiZWNoZGVsYXYgJT4lICAKICAgIG11dGF0ZShwZXJjZW50ID0gcm91bmQoY291bnQvIDE3OTQgKiAxMDApKSAlPiUgCiAgICBtdXRhdGUoc2V0X2ZhY3RvciA9ICJBdmVyYWdlIEJlY2hkZWwgU2NvcmVzIikKCmpvaW50YXYgPC0gcmJpbmQoYmVjaGRlbHNldGF2LCBiZWNoZGVsYXYpIAoKCmpvaW50YXYkY2xlYW5fdGVzdCA8LSBmYWN0b3Ioam9pbnRhdiRjbGVhbl90ZXN0LCBsZXZlbHMgPSBjKCJub3dvbWVuIiwgIm5vdGFsayIsICJtZW4iLCAiZHViaW91cyIsICJvayIpKQoKYGBgCgpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbHQ9IkEgc2NhdHRlciBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBJTURiIHNjb3JlIGFuZCB3b3JsZHdpZGUgYm94IG9mZmljZSBncm9zcyBmb3IgbW92aWVzIHdpdGggZGlmZmVyZW50IEJlY2hkZWwgdGVzdCBzY29yZXMuIEVhY2ggcG9pbnQgcmVwcmVzZW50cyBhIG1vdmllIGFuZCBpcyBjb2xvcmVkIGJhc2VkIG9uIGl0cyBCZWNoZGVsIHRlc3Qgc2NvcmUuIFRoZSBsZWdlbmQgc2hvd3MgdGhlIGZpdmUgQmVjaGRlbCB0ZXN0IHNjb3Jlczogbm8gd29tZW4sIG5vIHRhbGssIG1lbiwgZHViaW91cywgYW5kIG9rLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIElNRGIgc2NvcmUsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHdvcmxkd2lkZSBib3ggb2ZmaWNlIGdyb3NzIGluIG1pbGxpb25zLyBiaWxsaW9ucyBvZiBkb2xsYXJzLiBUaGUgdG9vbHRpcCBkaXNwbGF5cyB0aGUgbW92aWUgbmFtZSwgSU1EYiBzY29yZSwgYW5kIHdvcmxkd2lkZSBncm9zc2luZyBmb3IgZWFjaCBwb2ludC4ifQojRmlndXJlIDEKY29sb3JzIDwtIGMoIiNBQzI1MjgiLCAiI0U0NzkyQyIsICIjNzY0NDg0IiwgIiMzNDY0OTEiLCAiIzQ0ODc0NiIpCgpmaWcxPC1wbG90X2x5KGJlY2hkZWxzZXQsIHggPSB+c2NvcmUueCwgeSA9IH5gV29ybGR3aWRlQm94IE9mZmljZWAsIGNvbG9yID0gfmNsZWFuX3Rlc3QsIGNvbG9ycyA9IGNvbG9ycywgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdtYXJrZXJzJywKICBob3ZlcmluZm8gPSAndGV4dCcsCiAgdGV4dCA9IH5wYXN0ZSgnPC9icj4nLCBuYW1lLCAKICAgICAgICAgICAgICAgICc8L2JyPicsICJJTURCIFNjb3JlOiIsIHNjb3JlLngsIAogICAgICAgICAgICAgICAgJzwvYnI+JywgIldvcmxkd2lkZSBHcm9zc2luZzoiLCBjb21tYShgV29ybGR3aWRlQm94IE9mZmljZWApKSkgJT4lIAogIGxheW91dCh0aXRsZSA9ICdJTURCIFNjb3JlIHZzLiBBbW91bnQgb2YgTW9uZXkgR3Jvc3NlZCcsIAogICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAnSU1EQiBTY29yZScpLCAKICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gJ1dvcmxkd2lkZSBCb3ggT2ZmaWNlJyksIAogICAgICAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAiQmVjaGRlbCBUZXN0IFNjb3JlIiksCiAgICAgICAgICAgICAgICAgICAgICAgdGl0bGVzID0gbGlzdCh0b3Bncm9zc18yMCA9ICJUb3AgMjAgR3Jvc3NpbmciLCB0b3BzY29yZV8yMCA9ICJUb3AgMjAgU2NvcmVkIikpKQoKCgoKYGBgCgoKYGBge3IsZmlnLmFsdD0iVGhpcyBiYXIgZ3JhcGggc2hvd3MgdGhlIHRvdGFsIG51bWJlciBvZiBvc2NhciBhd2FyZHMgbm9taW5hdGlvbnMgb2YgdGhlIHRvcCAyMCBtb3ZpZXMgd2l0aCB0aGUgaGlnaGVzdCBXb3JsZHdpZGUgQm94IE9mZmljZSBieSBDYXRlZ29yeSBhbmQgV2lucyIsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLCBmaWcuaGVpZ2h0ID04LCBmaWcud2lkdGggPSAxMH0KI0ZpZ3VyZSAyCgpmaWcyPC1ib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3Jlb3JkZXIoTW92aWUsIHRvdGFsLC5mdW49c3VtKSxhbHBoYT13aW5uZXIsZmlsbD1mY3RfcmVvcmRlcihicm9hZF9jYXRlZ29yeSx3aW5uZXIpKSkgKyAKICBnZW9tX2JhcigpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikrCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoKSsKICBjb29yZF9mbGlwKCkrCiAgbGFicyh5PSJUb3RhbCBOb21pbmF0aW9ucyIseD0iTW92aWUiLHRpdGxlPSJUb3AgMjAgTW92aWVzIHdpdGggSGlnaGVzdCBXb3JsZHdpZGUgQm94IE9mZmljZSB2cyBPc2NhcnMgQXdhcmRzIixzdWJ0aXRsZSA9ICJCeSBDYXRlZ29yeSBhbmQgV2lucyIsZmlsbD0iQ2F0ZWdvcnkiLGFscGhhPSJXaW5uZXIiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiLHNpemU9MTYpLHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpLGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSxheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkKCgpgYGAKCgpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbHQ9IlRoaXMgc2NhdHRlciBwbG90IGRpc3BsYXlzIHRoZSB0b3AgMjAgaGlnaGVzdCBncm9zc2luZyBtb3ZpZXMgb2YgYWxsIHRpbWUgYnkgdGhlaXIgcHJvZml0IGFuZCB0aGUgbWFpbiBjaGFyYWN0ZXIncyByYWNlLiBJdCBzaG93cyB0aGF0IG91dCBvZiAyMCBtb3ZpZXMsIDIgaGFzIGEgbm9uLXdoaXRlIG1haW4gY2hhcmFjdGVyLiJ9CiNGaWd1cmUgMwpmaWczPC1ib3hfb2ZmaWNlX3RvcDIwX2luZm8gJT4lIAogIG11dGF0ZShQcm9maXQ9Z3Jvc3MtYnVkZ2V0KSAlPiUKICBnZ3Bsb3QoYWVzKHg9YnVkZ2V0LHk9Z3Jvc3MsY29sb3I9UmFjZSxzaXplPVByb2ZpdCkpICsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfbWluaW1hbCgpKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9jb21tYSgpKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfY29tbWEoKSkrCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX2NvbW1hKCkpKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb249IkUiKSsKICBsYWJzKHk9IlRvdGFsIEdyb3NzIix4PSJCdWRnZXQiLHRpdGxlPSJUb3AgMjAgTW92aWVzIHdpdGggSGlnaGVzdCBXb3JsZHdpZGUgQm94IE9mZmljZSIsc3VidGl0bGUgPSAiQnkgUHJvZml0IGFuZCBSYWNlIG9mIE1haW4gQ2hhcmFjdGVyIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkIixzaXplPTEyKSxwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9OCkpKwogIGFubm90YXRlKCJ0ZXh0Iix4PTIwMDAwMDAwMCx5PTE0MzAwMDAwMDAsbGFiZWw9IkJsYWNrIFBhbnRoZXIiLHNpemU9Myxjb2xvcj0icmVkMyIpKwogICBhbm5vdGF0ZSgidGV4dCIseD0yNjAwMDAwMDAseT0xNzUwMDAwMDAwLGxhYmVsPSJUaGUgTGlvbiBLaW5nICgyMDE5KSIsc2l6ZT0zLGNvbG9yPSJyZWQzIikKCiAgCmBgYAoKYGBge3IsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0UsZmlnLmFsdD0iQSBzdGFja2VkIGNvbHVtbiBjaGFydCBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGRpc3RyaWJ1dGlvbiBvZiBtb3ZpZXMgdGhhdCBwYXNzIHRoZSBCZWNoZGVsIHRlc3QgYnkgZGlmZmVyZW50IG1vdmllIHNldHMuIFRoZSB4LWF4aXMgcmVwcmVzZW50cyB0aGUgbW92aWUgc2V0cywgYW5kIHRoZSB5LWF4aXMgcmVwcmVzZW50cyB0aGUgcGVyY2VudGFnZSBvZiBtb3ZpZXMgdGhhdCBwYXNzIHRoZSBCZWNoZGVsIHRlc3QuIFRoZSBjaGFydCBpcyBkaXZpZGVkIGludG8gZml2ZSBjYXRlZ29yaWVzIGJhc2VkIG9uIHRoZSBCZWNoZGVsIHRlc3Qgc2NvcmU6IG5vIHdvbWVuLCBubyB0YWxrLCBtZW4sIGR1YmlvdXMsIGFuZCBvay4gVGhlIHRvb2x0aXAgc2hvd3MgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIGZvciBlYWNoIGNhdGVnb3J5IGFuZCBtb3ZpZSBzZXQuIn0KI0ZpZ3VyZSA0CgoKZmlnNDwtaGNoYXJ0KGpvaW50YXYsICJjb2x1bW4iLCBoY2Flcyh4ID0gc2V0X2ZhY3RvciwgeSA9IGNvdW50LCBncm91cCA9IGNsZWFuX3Rlc3QpLCBzdGFja2luZyA9ICJwZXJjZW50IikgJT4lIAogIGhjX3RpdGxlKHRleHQgPSAiQmVjaGRlbCBUZXN0IFNjb3JlcyIpICU+JSAKICBoY19jb2xvcnMoY29sb3JzKSAlPiUgCiAgaGNfdG9vbHRpcChwb2ludEZvcm1hdCA9ICJ7c2VyaWVzLm5hbWV9OiB7cG9pbnQucGVyY2VudGFnZTouMWZ9JSIpICU+JSAKICBoY195QXhpcyh0aXRsZSA9ICJQZXJjZW50YWdlIiwgbGFiZWxzID0gbGlzdChmb3JtYXQgPSAne3ZhbHVlfSUnKSkgJT4lCiAgaGNfeEF4aXModGl0bGUgPSBOVUxMKSAlPiUgCiAgaGNfY29sb3JzKGNvbG9ycykgJT4lIAogIGhjX2xlZ2VuZChlbmFibGVkID0gVFJVRSkKYGBgCgojIFRoZSBjdXJyZW50IGFuYXRvbXkgb2YgYSBnb29kIG1vdmllOiBDYW4gd2UgZG8gYmV0dGVyPyAKCiAgRXZlciBzaW5jZSB0aGUg4oCcR29sZGVuIEFnZeKAnSBvZiBjaW5lbWEgaW4gdGhlIDE5MzBzIHRoYXQgbWFya2VkIHNpbGVudCBmaWxtIGEgdGhpbmcgb2YgdGhlIHBhc3QsIHRoZSBmaWxtIGluZHVzdHJ5IGhhcyB3aXRuZXNzZWQgdW5wYXJhbGxlbGVkIHN1Y2Nlc3MgYW5kIGdyb3d0aC4gRnJvbSB0aGUgZmlyc3QgdGVjaG5pY29sb3IgbW92aWVzIGxpa2UgVGhlIFdpemFyZCBvZiBPeiBhbmQgR29uZSBXaXRoIFRoZSBXaW5kIHRvIHRoZSBjb21wdXRhdGlvbmFsbHkgYW5pbWF0ZWQgVGhlIE1hdHJpeCwgSnVyYXNzaWMgUGFyaywgYW5kIHRoZSBmaXJzdCBmdWxseSBjb21wdXRlci1hbmltYXRlZCBmaWxtLCBUb3kgU3RvcnksIHRoZSBpbmR1c3RyeSBvZiBtb3Rpb24gcGljdHVyZXMgaGFzIGNvbnRyaWJ1dGVkIGdyZWF0bHkgbm90IG9ubHkgdG8gdGVjaG5vbG9neSBidXQgYWxzbyB0aGUgZ2xvYmFsIGVjb25vbXkuIEVzcGVjaWFsbHkgaW4gdGhlIGN1cnJlbnQgY2hhbGxlbmdpbmcgZWNvbm9teSBhbmQgdGhlcmUgaGFzIGJlZW4gYSBzaGFycCBkZWNsaW5lIGluIHRoZWF0ZXIgYXVkaWVuY2XigJRbc2hyaW5raW5nIGJ5IGhhbGYgaW4gdGhlIGxhc3QgNCB5ZWFyc11odHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JTURiKSwgZmlsbSBkaXN0cmlidXRvcnMgYXJlIGhlc2l0YW50IHRvIHRha2Ugb24gYSBtb3ZpZSB1bmxlc3MgdGhleSBjYW4gc2VlIGl0cyBzdWNjZXNzIGZpcnN0IGhhbmQuIFRoZXJlZm9yZSwgYm94LW9mZmljZSwgb3IgdGhlIGVudGlyZSBlYXJuaW5ncyBnZW5lcmF0ZWQgdGhyb3VnaCBtb3ZpZSB0aWNrZXQgc2FsZXMsIGhhcyBiZWVuIHJlY29nbml6ZWQgYXMgb25lIG9mIHRoZSBwcmltYXJ5IGluZGljYXRvcnMgdG8gY29tcGFyZSBmaWxtIHN1Y2Nlc3MuIE1hbnkgcmVseSBvbiBpdCB0byBkZWNpZGUgd2hldGhlciB0byBib3RoIHByb2R1Y2UgYW5kIHdhdGNoIGEgZmlsbS4gSG93ZXZlciwgYXJlIGhpZ2ggZ3Jvc3NpbmcgbW92aWVzIGFjdHVhbGx54oCmIGdvb2Q/IElmIHNvLCB3aGF0IGVsc2UgY2FuIHdlIHVzZSB0byBtZWFzdXJlIHRoZW0/ICAKCiAgT25lIG9mIHRoZSBwb3B1bGFyIG90aGVyIGluZGljYXRvcnMgdXNlZCB3b3JsZHdpZGUgdG8gYXNzZXNzIGEgbW92aWUgaXMgSU1EYiByYXRpbmcgKG9yIEludGVybmF0aW9uYWwgTW92aWUgRGF0YWJhc2UpLiBJTURiIHJhdGluZyBhbGxvd3MgWzgzIG1pbGxpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZykgb2YgaXRzIHJlZ2lzdGVyZWQgdXNlcnMgIHRvIGNhc3QgYSB2b3RlIChmcm9tIDEgdG8gMTApIG9uIGV2ZXJ5IHJlbGVhc2VkIHRpdGxlIGluIHRoZSBkYXRhYmFzZS4gVGhlc2Ugdm90ZXMgYXJlIHRoZW4gYWdncmVnYXRlZCBhbmQgc3VtbWFyaXplZCBhcyBhIHNpbmdsZSBJTURiIHJhdGluZyB2aXNpYmxlIG9uIElNRGIuY29tLiBBY2Nlc3NpYmxlIHRvIGFueW9uZSwgYW55d2hlcmUsIHRoZXNlIHJhdGluZ3MgYXJlIGEgc2ltcGxpZmllZCB3YXkgdG8gc2VlIHdoYXQgcGVvcGxlIGFsbCBvdmVyIHRoZSB3b3JsZCB0aGluayBhYm91dCBtb3ZpZXMgYW5kIGhhdmUgYmVlbiBhbiBvZnRlbi11c2VkIGluZGljYXRvciBmb3IgYSBmaWxt4oCZcyBwb3B1bGFyaXR5L3F1YWxpdHkuIFRoaXMgbGVkIHVzIHRvIHdvbmRlcjogKkhvdyBkbyB0aGUgbW9zdCBwcm9maXRhYmxlIG1vdmllcyByYW5rIG9uIHRoZSBJTURiIHdlYnNpdGU/KiAKCgpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxmaWcuYWx0PSJBIHNjYXR0ZXIgcGxvdCBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgSU1EYiBzY29yZSBhbmQgd29ybGR3aWRlIGJveCBvZmZpY2UgZ3Jvc3MgZm9yIG1vdmllcyB3aXRoIGRpZmZlcmVudCBCZWNoZGVsIHRlc3Qgc2NvcmVzLiBFYWNoIHBvaW50IHJlcHJlc2VudHMgYSBtb3ZpZSBhbmQgaXMgY29sb3JlZCBiYXNlZCBvbiBpdHMgQmVjaGRlbCB0ZXN0IHNjb3JlLiBUaGUgbGVnZW5kIHNob3dzIHRoZSBmaXZlIEJlY2hkZWwgdGVzdCBzY29yZXM6IG5vIHdvbWVuLCBubyB0YWxrLCBtZW4sIGR1YmlvdXMsIGFuZCBvay4gVGhlIHgtYXhpcyByZXByZXNlbnRzIHRoZSBJTURiIHNjb3JlLCBhbmQgdGhlIHktYXhpcyByZXByZXNlbnRzIHRoZSB3b3JsZHdpZGUgYm94IG9mZmljZSBncm9zcyBpbiBtaWxsaW9ucy8gYmlsbGlvbnMgb2YgZG9sbGFycy4gVGhlIHRvb2x0aXAgZGlzcGxheXMgdGhlIG1vdmllIG5hbWUsIElNRGIgc2NvcmUsIGFuZCB3b3JsZHdpZGUgZ3Jvc3NpbmcgZm9yIGVhY2ggcG9pbnQuIn0KZmlnMQpgYGAKICBGcm9tIG91ciB2aXN1YWxpemF0aW9uIGFib3ZlLCB0aGUgdG9wIDIwIGdyb3NzaW5nIGZpbG1zIGhhdmUgYSByYW5nZSBvZiBzY29yZXMgZnJvbSA2LjIgdG8gOC40IHN0YXJzLiBDb252ZXJzZWx5LCB0aGUgdG9wIDIwIHNjb3JlZCBtb3ZpZXMgb24gSU1EYiBnbG9iYWxseSBncm9zc2VkIGJldHdlZW4gMjgsNDE5LDE1OSBhbmQgMSwxMjAsMjEwLDg5NiBVLlMuIERvbGxhcnMuIFdoZW4gY29tcGFyaW5nIHRoZSBJTURic2NvcmUgYW5kIGFtb3VudCBvZiBtb25leSBncm9zc2VkLCB3ZSBjYW4gb2JzZXJ2ZSB0aGF0IHRoZXJlIGlzbuKAmXQgbXVjaCBvZiBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSByYXRpbmcgb2YgYSBmaWxtIChvciBob3cg4oCcb2JqZWN0aXZlbHkgZ29vZOKAnSBhIG1vdmllIGlzKSBhbmQgdGhlIGFtb3VudCBvZiBtb25leSBpdCBtYWtlcy4KCiAgT24gdGhlIG90aGVyIGhhbmQsIHRvIGludmVzdGlnYXRlIG9waW5pb25zIG9mIGZpbG1zIGZyb20gcHJvZmVzc2lvbmFscyBhbmQgdHJ1c3RlZCBtZW1iZXJzIG9mIHRoZSBmaWxtIGluZHVzdHJ5LCB3ZSBjYW4gdHVybiB0byB0aGUgQWNhZGVteSBBd2FyZHMuIAoKCmBgYHtyLGZpZy53aWR0aD0xMCxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxmaWcuYWx0PSJUaGlzIHNjYXR0ZXIgcGxvdCBkaXNwbGF5cyB0aGUgdG9wIDIwIGhpZ2hlc3QgZ3Jvc3NpbmcgbW92aWVzIG9mIGFsbCB0aW1lIGJ5IHRoZWlyIHByb2ZpdCBhbmQgdGhlIG1haW4gY2hhcmFjdGVyJ3MgcmFjZS4gSXQgc2hvd3MgdGhhdCBvdXQgb2YgMjAgbW92aWVzLCAyIGhhcyBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3Rlci4ifQpmaWcyCmBgYAoKICBJdCBzZWVtcyBsaWtlIGEgbW92aWXigJlzIHJldmVudWUgaXMgbm90IGEgc3Ryb25nIGluZGljYXRvciBmb3IgaXRzIGFjY29sYWRlcy4gQW1vbmcgdGhlIHRvcCAyMCBtb3ZpZXMgd2l0aCB0aGUgaGlnaGVzdCB3b3JsZHdpZGUgYm94IG9mZmljZSBhbmQgdGhlaXIgT3NjYXJzIGF3YXJkcywgb25seSAxMSBtb3ZpZXMgaGFkIGFueSBub21pbmF0aW9ucyBhdCBhbGwuIEZ1cnRoZXJtb3JlLCB0aGlzIGxpc3QgZ2V0cyBldmVuIG1vcmUgbmFycm93ZWQgZG93biBhcyB3ZSBsb29rIGludG8gd2lucy9sb3Nlcy4gVGl0YW5pYywgQXZhdGFyLCBCbGFjayBQYW50aGVyLCBhbmQgRnJvemVuIGFyZSB0aGUgb25seSBtb3ZpZXMgaW4gdGhlIHRvcCAyMCBoaWdoZXN0IHdvcmxkd2lkZSBncm9zc2luZyBtb3ZpZXMgdG8gaGF2ZSBoYWQgYXQgbGVhc3Qgb25lIG5vbWluYXRpb24gYW5kIHdvbiwgd2l0aCBUaXRhbmljIGFzIHRoZSBtb3N0IHByb2xpZmljIHdpdGggMTEgb3V0IG9mIDE0IGNhdGVnb3JpZXMgKGFmdGVyIGdyb3VwaW5nIHNvbWUgb2YgdGhlbSB0b2dldGhlcikuCgogIFRoZSBPc2NhcnMsIGhvd2V2ZXIsIGFyZSBub3QgYW4gb2JqZWN0aXZlIG1lYW5zIG9mIGF3YXJkc2hpcC4gSW4gMjAxNSwgdGhlIGFjYWRlbXkg4oCcYXdhcmRlZCBhbGwgMjAgYWN0aW5nIG5vbWluYXRpb25zIHRvIHdoaXRlIGFjdG9ycyBmb3IgdGhlIGZpcnN0IG9mIHR3byBjb25zZWN1dGl2ZSB5ZWFycywgaW5zcGlyaW5nIEFwcmlsIFJlaWduIHRvIGNyZWF0ZSB0aGUgaGFzaHRhZyAjT3NjYXJzU29XaGl0ZeKAnSBbKFVnd3UsIDIwMjApXShodHRwczovL3d3dy5ueXRpbWVzLmNvbS8yMDIwLzAyLzA2L21vdmllcy9vc2NhcnNzb3doaXRlLWhpc3RvcnkuaHRtbCkuIExlYXZpbmcgdGhlIGRldGVybWluYXRpb24gb2YgZmlsbSBzdWNjZXNzIHRvIHRoZSBBY2FkZW15IHNlZW1zIHRvIHlpZWxkIGEgY2VsZWJyYXRpb24gb2Ygd2hpdGUgY3JlYXRvcnMgYW5kIGFydGlzdHMsIGV4Y2x1ZGluZyBhIHdob2xlIHdvcmxkIG9mIGRpdmVyc2UgY2luZW1hLiAKCgpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxmaWcuYWx0PSJUaGlzIHNjYXR0ZXIgcGxvdCBkaXNwbGF5cyB0aGUgdG9wIDIwIGhpZ2hlc3QgZ3Jvc3NpbmcgbW92aWVzIG9mIGFsbCB0aW1lIGJ5IHRoZWlyIHByb2ZpdCBhbmQgdGhlIG1haW4gY2hhcmFjdGVyJ3MgcmFjZS4gSXQgc2hvd3MgdGhhdCBvdXQgb2YgMjAgbW92aWVzLCAyIGhhcyBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3Rlci4ifQpmaWczCmBgYAoKICBBcyBvZiAyMDIwLCBbYWxtb3N0IGhhbGYgb2YgdGhlIFUuUy4gcG9wdWxhdGlvbiAoNDIuMiUpIGFyZSBwZW9wbGUgb2YgY29sb3JdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1JhY2VfYW5kX2V0aG5pY2l0eV9pbl90aGVfVW5pdGVkX1N0YXRlcyM6fjp0ZXh0PUFzJTIwb2YlMjAyMDIwJTJDJTIwV2hpdGUlMjBBbWVyaWNhbnMsbWlub3JpdHklMkMlMjBtYWtpbmclMjB1cCUyMDEyLjElMjUpLiBZZXQsIEhvbGx5d29vZCBmYWlscyB0byBjb25zaWRlciB0aGVtIHdoZW4gbWFraW5nIG1vdmllcy4gSW4gdGhlIHRvcCAyMCBoaWdoZXN0IGdyb3NzaW5nIG1vdmllcyBvZiBhbGwgdGltZSwgb25seSAyIG1vdmllcyBmZWF0dXJlZCBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3RlcuKAlGJvdGggb2Ygd2hpY2ggd2VyZSBCbGFjayBtYWxlcy4gTm9uZSBvZiB0aGVzZSBtb3ZpZXMgYXJlIGluIHRoZSB0b3AgNSBvZiB0aGlzIGxpc3QgaW4gdGVybXMgb2YgcHJvZml0IGFuZCBncm9zc2luZyB3aGlsZSBvdGhlciB1bmRlcnJlcHJlc2VudGVkIGRlbW9ncmFwaGljcyAoTGF0aW5lcywgRWFzdC9Tb3V0aC9Tb3V0aGVhc3QgQXNpYW5zLCBOYXRpdmUgQW1lcmljYW5zLCBBZnJvIExhdGlub3MsIGV0Yy4pIGFyZSBsZWZ0IGNvbXBsZXRlbHkgb2ZmIHRoZSBzY3JlZW4uIAoKICBGdXJ0aGVybW9yZSwgaW4gdGhlIGhpc3Rvcnkgb2YgdGhlIE9zY2FycyBvbmx5IHRocmVlIHdvbWVuIGhhdmUgd29uIHRoZSBjb3ZldGVkIGJlc3QgZGlyZWN0b3IgdGl0bGUuIFRoaXMgcmVmbGVjdHMgYSBnZW5kZXJlZCBtZWFzdXJlIG9mIHN1Y2Nlc3Mgd2l0aGluIHRoZSBmaWxtIGluZHVzdHJ5LCB3aGVyZSBtb3N0IG9mIHRoZSBwcmFpc2UgZ29lcyB0byBmaWxtcyBhYm91dCBhbmQgY3JlYXRlZCBieSBjaXMgbWVuLiBUbyBtZWFzdXJlIHRoZSByZXByZXNlbnRhdGlvbiBvZiB3b21lbiBpbiBmaWxtcywgd2UgY2FuIHR1cm4gdG8gdGhlIFtCZWNoZGVsIHRlc3RdKGh0dHBzOi8vYmVjaGRlbHRlc3QuY29tLykgd2hpY2ggd2FzIHBvcHVsYXJpemVkIGJ5IEFsaXNvbiBCZWNoZGVsLiBUaGUgdGVzdCBuYW1lcyB0aHJlZSBzaW1wbGUgY3JpdGVyaWE6ICgxKSBpdCBoYXMgdG8gaGF2ZSBhdCBsZWFzdCB0d28gd29tZW4gaW4gaXQsIHdobyAoMikgd2hvIHRhbGsgdG8gZWFjaCBvdGhlciwgYWJvdXQgKDMpIHNvbWV0aGluZyBiZXNpZGVzIGEgbWFuLiBBbHRob3VnaCB0aGlzIHRlc3Qgc2VlbXMgZWFzeSBlbm91Z2gsIG9ubHkgMjUlIG9mIHRoZSB0b3Agc2NvcmVkIGZpbG1zIGFuZCA1MCUgb2YgdGhlIHRvcCBncm9zc2luZyBmaWxtcyBwYXNzZWQuIEludGVyZXN0aW5nbHkgZW5vdWdoLCB3aGVuIGNvbXBhcmluZyB0aGUgdHdvIGRhdGFzZXRzIHRvIGFuIGF2ZXJhZ2UgQmVjaGRlbCB0ZXN0IHNjb3JlIGJyZWFrZG93biwgd2UgY2FuIHNlZSB0aGF0IHRoZSBoaWdoZXN0IGdyb3NzaW5nIGZpbG1zIGFsbCBoYXZlIHdvbWVuIGFuZCBhbiBhYm92ZSBhdmVyYWdlIHNjb3JlIG9mICJvayIgYW5kICJkdWJpb3VzIi4gSG93ZXZlciwgdGhlIGhpZ2hlc3Qgc2NvcmVkIGZpbG1zIGhhdmUgbGVzcyB0aGFuIGF2ZXJhZ2UgIm9rIiBhbmQgZHViaW91cyIgc2NvcmVzLiAKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLGZpZy5hbHQ9IkEgc3RhY2tlZCBjb2x1bW4gY2hhcnQgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBkaXN0cmlidXRpb24gb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0IGJ5IGRpZmZlcmVudCBtb3ZpZSBzZXRzLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIG1vdmllIHNldHMsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0LiBUaGUgY2hhcnQgaXMgZGl2aWRlZCBpbnRvIGZpdmUgY2F0ZWdvcmllcyBiYXNlZCBvbiB0aGUgQmVjaGRlbCB0ZXN0IHNjb3JlOiBubyB3b21lbiwgbm8gdGFsaywgbWVuLCBkdWJpb3VzLCBhbmQgb2suIFRoZSB0b29sdGlwIHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIG1vdmllcyBmb3IgZWFjaCBjYXRlZ29yeSBhbmQgbW92aWUgc2V0LiJ9CmZpZzQKYGBgCgoKICBUaGUgdHJlbmQgd2UgaGF2ZSBpZGVudGlmaWVkIGhlcmUgaXMgc3Ryb25nOiBtb3ZpZXMgdGhhdCBtYWtlIHRoZSBtb3N0IG1vbmV5IGFyZSBtb3N0IG9mdGVuIHRoYW4gbm90IHdoaXRlLSwgbWFsZS0sIGFuZCBFdXJvLWNlbnRyaWMuIEV2ZW4gbG9va2luZyBiZXlvbmQgdGhlIGRvbGxhciwgd2UgY2FuIHNlZSBob3cgc2NvcmluZyBzeXN0ZW1zIGFuZCBhd2FyZHMgYXJlIGJpYXNlZCB0b3dhcmRzIHRoaXMgZGVtb2dyYXBoaWMgYXMgd2VsbC4gQWx0aG91Z2ggdGhlIEFtZXJpY2FuIG1vdmllIGluZHVzdHJ5IGNvbnRpbnVlcyBhY2hpZXZlZCBjb21tZXJjaWFsIHN1Y2Nlc3MsIGl0IGhpc3RvcmljYWxseSBoYXMsIGFuZCBjb250aW51ZXMgdG8sIGxhY2sgc3VmZmljaWVudCByZXByZXNlbnRhdGlvbi4gV2hpbGUgSG9sbHl3b29kIGhhcyB1bmRvdWJ0ZWRseSBjcmVhdGVkIG5vdGFibGUgZmlsbXMgbGlrZSBUaGUgV2l6YXJkIG9mIE96LCBHb25lIFdpdGggVGhlIFdpbmQsIFRoZSBNYXRyaXgsIGFuZCBKdXJhc3NpYyBQYXJrLCB0aGUgaW5kdXN0cnkncyBmb2N1cyBvbiB3aGl0ZSBtYWxlcyBoYXMgcmVzdWx0ZWQgaW4gYSBzaWduaWZpY2FudCBsb3NzIG9mIGRpdmVyc2UgcGVyc3BlY3RpdmVzIGFuZCBjaW5lbWF0aWMgZXhwZXJpZW5jZXMuIEl0IHNlZW1zIGxpa2Ugd2hlbiB3ZSBhcmUgdHJ5aW5nIHRvIGp1ZGdlIGEgbW92aWUsIHdlIHNob3VsZCBoYXZlIGEgYnJvYWRlciByZXBlcnRvaXJlIG9mIG1lYXN1cmVtZW50cyBmb3IgaG93ICpnb29kKiBpdCBpcyBvdGhlciB0aGFuIGp1c3QgbW9uZXkuICAgCgojIERhdGEgRGVzY3JpcHRpb24gCgpBbGwgb2Ygb3VyIGRhdGFzZXRzIHdhcyBzY3JhcGVkIGZyb20gcHVibGljIGRvbWFpbnMgc3VjaCBhcyBba2FnZ2xlLmNvbV0oaHR0cHM6Ly9rYWdnbGUuY29tLykgYW5kIFtmaXZldGhpcnR5ZWlnaHRdKGh0dHBzOi8vZml2ZXRoaXJ0eWVpZ2h0LmNvbS8pLiBJbiB0b3RhbCwgd2UgdXNlZCA0IGRhdGFzZXRzIHRvIHN1cHBvcnQgb3VyIHJlc2VhcmNoIHBhcGVyOiAKPGJyPgoKMS4gICBUaGUgT3NjYXIgQXdhcmQsIFsxOTI3IC0gMjAyM10oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy91bmFuaW1hZC90aGUtb3NjYXItYXdhcmQpOgogICsgMTAsNzY1IE9zY2FyIG5vbWluYXRpb25zIAogICsgc2NyYXBlZCBmcm9tIHRoZSBPZmZpY2lhbCBBY2FkZW15IEF3YXJkcwogICsgNyB2YXJpYWJsZXM6IHllYXIsIG5hbWUsIGZpbG0sIGNhdGVnb3JpZXMsIHdpbiwuLi4KPGJyPgoyLiAgIE1vdmllIEluZHVzdHJ5OiBGb3VyIGRlY2FkZXMgb2YgbW92aWVzLCBbMTk4Ni0yMDE2XShodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2RhbmllbGdyaWphbHZhcy9tb3ZpZXMpOgogICsgNjgyMCBtb3ZpZXMgaW4gdGhlIGRhdGFzZXQgKGFyb3VuZCAyMjAgbW92aWVzIHBlciB5ZWFyKQogICsgMTUgdmFyaWFibGVzOiBidWRnZXQsIGNvbXBhbnksIGNvdW50cnksIGRpcmVjdG9yLCBnZW5yZSwgbmFtZSwuLi4uCjxicj4KMy4gICBBbGwgVGltZSBXb3JsZHdpZGUgQm94IE9mZmljZSwgWzE5MzktMjAyMV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy9ra2hhbmRla2FyL2FsbC10aW1lLXdvcmxkd2lkZS1ib3gtb2ZmaWNlKQogICsgY29udGFpbnMgdGhlIHRvcCBtb3ZpZXMgYmFzZWQgb24gdGhlIGN1bXVsYXRpdmUgd29ybGR3aWRlIGJveCBvZmZpY2UKICArIDc1MTIgbW92aWVzIGFuZCA2IHZhcmlhYmxlczogcmFuaywgd29ybGR3aWRlLWludGVybmF0aW9uYWwtZG9tZXN0aWMgYm94IG9mZmljZSwuLi4KPGJyPgo0LiBCZWNoZGVsIFRlc3QsIDE5NzAtMjAxMyAoZnJvbSBsaWJyYXJ5KGZpdmV0aGlydHllaWdodCkpCiAgKyB0ZXN0cyB3aGV0aGVyIG1vdmllcyBtZWV0IHRoZSBmb2xsb3dpbmcgY3JpdGVyaWE6IFRoZXJlIGFyZSDiiaUgMiAobmFtZWQpIGZlbWFsZSBjaGFyYWN0ZXJzO3RoZXNlIHdvbWVuIHRhbGsgdG8gZWFjaCBvdGhlOyBhYm91dCBzb21ldGhpbmcgb3RoZXIgdGhhbiBhIG1hbi4KICArIDE3OTQgbW92aWVzLCAxNSB2YXJpYWJsZXM6IG1vdmllLCByZXN1bHQsIGdyb3NzaW5ncywgLi4uCiAgCiMgTGltaXRhdGlvbnMKCiMjIERhdGEgCgogIFRoZXJlIGFyZSBzb21lIGxpbWl0YXRpb25zIGluIHRoZSBkYXRhc2V0cy4gRmlyc3Rtb3N0LCB3aGVuIGNvbXBhcmluZyB0aGUgd29ybGR3aWRlIGdyb3NzaW5nIGFtb3VudCBvZiBtb3ZpZXMsIHdlIHdlcmUgdW5hYmxlIHRvIGFjY291bnQgZm9yIGluZmxhdGlvbi4gVGhlIGRhdGFzZXQg4oCcQWxsIFRpbWUgV29ybGR3aWRlIEJveCBPZmZpY2XigJ0gc2NyYXBlZCB0aGUgdGhlIGFtb3VudHMgb2YgaW50ZXJuYXRpb25hbCBncm9zc2luZyBmcm9tIDE5MzkgdG8gMjAyMSwgYnV0IElNRGIgc3RhdGVzIHRoYXQgWyJhbGwgZmlndXJlcyBhcmUgbm90IGFkanVzdGVkIGZvciBpbmZsYXRpb24iXShodHRwczovL2hlbHAuaW1kYi5jb20vYXJ0aWNsZS9jb250cmlidXRpb24vdGl0bGVzL2J1c2luZXNzLWltZGJwcm8tb25seS9HRUpVV1NCQjZXWEgzUlo2IykuIAo8YnI+CiAgQWNjb3JkaW5nIHRvIGEgTWlubmVzb3RhbiBpbmZsYXRpb24gY2FsY3VsYXRvciBbMSBVLlMuIERvbGxhciBpbiAxOTM5IGlzIHdvcnRoICQxOS40OCB0b2RheV0oaHR0cHM6Ly93d3cubWlubmVhcG9saXNmZWQub3JnL2Fib3V0LXVzL21vbmV0YXJ5LXBvbGljeS9pbmZsYXRpb24tY2FsY3VsYXRvciksIHdoaWNoIG1lYW5zIHRoYXQgdGhlIGFtb3VudCBvZiBtb25leSBvY2N1cnJpbmcgaW4gZGlmZmVyZW50IHRpbWUgcGVyaW9kcyBpcyBub3Qgc2NhbGVkIHRvIHNpemUuIEFkZGl0aW9uYWxseSwgaW4gdGhlIGRhdGFzZXQgdXNlZCBmb3IgdGhlIHJhY2lhbCBkaXN0cmlidXRpb24gb2YgT3NjYXJzIHdpbm5lcnMsIHRoZSBkYXRhc2V0IG9ubHkgY29udGFpbmVkIHRoZSByYWNpYWwgaWRlbnRpdGllcyBvZiBiZXN0IGRpcmVjdG9ycywgYWN0b3JzLCBhbmQgYWN0cmVzc2VzLiBUaGlzIGV4Y2x1ZGVzIDIxIG90aGVyIGF3YXJkIGNhdGVnb3JpZXMsIHdoaWNoIGNvdWxkIGhhdmUgZ2l2ZW4gbW9yZSBhY2N1cmF0ZSBpbnNpZ2h0IGludG8gdGhlIGRlbW9ncmFwaGljcyBvZiBPc2NhcnMgd2lubmVycyBhY3Jvc3MgdGhlIGVudGlyZSBhd2FyZCBjZXJlbW9ueS4gICAKPGJyPgogIEZ1cnRoZXJtb3JlLCB3ZSB1c2VkIElNRGIgcmF0aW5ncyB0byBpbnZlc3RpZ2F0ZSBob3cgbW92aWVzIG9mIHZhcmlvdXMgZ3Jvc3NpbmcgYW1vdW50cyBhcmUgc2NvcmVkLCBidXQgaXQgaXMgd29ydGggbm90aW5nIHRoYXQgdGhlIHdlYnNpdGUgY2FsY3VsYXRlcyBhbiBvdmVyYWxsIHNjb3JlIGZyb20gcmVnaXN0ZXJlZCB1c2VycyBjYXN0aW5nIHRoZWlyIHZvdGVzLiBIb3dldmVyLCB0aGVyZSBoYXMgYmVlbiBhIGxhcmdlciBkaXNjdXNzaW9uIGFyb3VuZCB0aGUgbWV0aG9kb2xvZ3kgb2YgdGhpcyBzeXN0ZW0gb2YgbW92aWUtcmF0aW5nLCB3aXRoIHNvbWUgcGVvcGxlIGRlZW1pbmcgb25saW5lIG1vdmllIHZvdGluZyBzeXN0ZW1zIHRvIGJlIGluZWZmZWN0aXZlLiBBZGRpdGlvbmFsbHksIGl0IHdhcyBmb3VuZCB0aGF0IOKAnG1vc3QgSU1EYiB2b3RlcnMgYXJlIG1hbGUsIHdoaWNoIHNlZW1zIHRvIHNrZXcgdGhlIHJhbmtpbmcgaW4gZmF2b3VyIG9mIGZpbG1zIHRoYXQgYXJlIGFpbWVkIG1vcmUgdG93YXJkcyBtZW7igJ0gWyhSZXlub2xkcywgMjAxNyldKGh0dHBzOi8vd3d3LndpcmVkLmNvLnVrL2FydGljbGUvd2hpY2gtZmlsbS1yYW5raW5nLXNpdGUtc2hvdWxkLWktdHJ1c3Qtcm90dGVuLXRvbWF0b2VzLWltZGItbWV0YWNyaXRpYykuIEl0IGlzIHdvcnRoIGFja25vd2xlZGdpbmcgdGhhdCBJTURiIHJhdGluZ3MgYXJlIGEgYmlhc2VkIHN5c3RlbSBvZiByYW5raW5nIGEgZmlsbSwgaG93ZXZlciwgdGhpcyBmdXJ0aGVyIGFpZHMgb3VyIHJlc2VhcmNoIHF1ZXN0aW9uIGluIGlsbHVzdHJhdGluZyB0aGUgY29tcGxpY2F0aW9ucyB0aGF0IGNvbWUgd2l0aCBkZXRlcm1pbmluZyB3aGV0aGVyIGEgbW92aWUgaXMg4oCcZ29vZOKAnS4gCjxicj4KICBBbm90aGVyIGxpbWl0YXRpb24gb2YgdGhpcyBwcm9qZWN0IGlzIHVzaW5nIFRoZSBCZWNoZGVsIHRlc3QgYXMgYSBtZWFzdXJlIG9mIGdlbmRlciBlcXVhbGl0eSBpbiBmaWxtLiBUaGUgQmVjaGRlbCB0ZXN0IGlzIGFuIGluZmFtb3VzIG1lYXN1cmUgb2YgSG9sbHl3b29k4oCZcyBnZW5kZXIgaW1iYWxhbmNlLCBob3dldmVyIGl0IGlzIGFuIG92ZXJzaW1wbGlmaWVkIG1lYW5zIG9mIGFuYWx5emluZyB0aGUgcm9sZSBvZiB3b21lbiBpbiBmaWxtLiBJdCBhc2tzIHRocmVlIHF1ZXN0aW9ucyBvZiBhIG1vdmllLCBhbmQgd2hpbGUgYXN0b25pc2hpbmdseSBtYW55IGZpbG1zIGRvIG5vdCBwYXNzIHRoYXQgYmFyLCB0aGUgc2ltcGxpY2l0eSBvZiB0aGlzIHRlc3Qg4oCcZG9lc27igJl0IGFkZHJlc3MgdGhlIGNvcmUgaW5lcXVhbGl0aWVzIGluIEhvbGx5d29vZCBmaWxtc+KAnSBbKEhpY2tleSBldCBhbCwgMjAxNyldKGh0dHBzOi8vcHJvamVjdHMuZml2ZXRoaXJ0eWVpZ2h0LmNvbS9uZXh0LWJlY2hkZWwvKS4gSW4gdGhlIGRhdGFzZXQgd2UgdXNlZCwgdGhlcmUgd2VyZSBtYW55IGluc3RhbmNlcyBvZiDigJxkdWJpb3Vz4oCdIHdoZXJlIHRoZSByb2xlIG9mIHdvbWVuIGluIHRoZSBmaWxtIHdlcmUgZGViYXRlZCwgYW5kIHRoZXJlZm9yZSwgdGhlIHBhc3MvZmFpbCBzY29yZSBjb3VsZG7igJl0IGJlIGRldGVybWluZWQuIFRvIGNyZWF0ZSBhIG1vcmUgaG9saXN0aWMgYW5hbHlzaXMgb2YgZ2VuZGVyIGVxdWFsaXR5IGluIEhvbGx5d29vZCBpbiB0aGUgZnV0dXJlLCBpdCBpcyB3b3J0aCByZXNlYXJjaGluZyBuZXcgdGVzdHMgdGhhdCBpbmNsdWRlIG5vbi1iaW5hcnkgcGVvcGxlLCBhbmQgZXhwYW5kIHRoZSByZXF1aXJlbWVudHMuIEZvciBpZGVhcywgd2UgY2FuIHR1cm4gdG8g4oCcV2UgcGl0dGVkIDUwIG1vdmllcyBhZ2FpbnN0IDEyIG5ldyB3YXlzIG9mIG1lYXN1cmluZyBIb2xseXdvb2TigJlzIGdlbmRlciBpbWJhbGFuY2XigJ0gd2hpY2ggc3VnZ2VzdHMgbmV3IHRlc3RzIHRoYXQgbG9vayBiZXlvbmQgd2hpdGUgd29tZW4sIGFuZCB0aGUgY2FzdCBhbmQgY3JldyBvZiB0aGUgZmlsbS4gCgojIyBWaXN1YWxpemF0aW9ucy8gT3ZlcmFsbCBSZXNlYXJjaAoKICBPdXIgYXR0ZW1wdCB0aHJvdWdob3V0IHRoaXMgcmVzZWFyY2ggaXMgdG8gc3VnZ2VzdCBkaWZmZXJlbnQgbWV0cmljcyB0byBjb21wYXJlIGFuZCBjb25jbHVkZSBhIG1vdmllIHF1YWxpdHkgYW5kIHB1YmxpYyBwZXJmb3JtYW5jZSBvdGhlciB0aGFuIGl0cyByZXZlbnVlIGFuZCBwcm9maXQgcmV0dXJucy4gRGVzcGl0ZSB0aGUgdmFyaW91cyBpbmRpY2F0b3JzIHdlIGhhdmUgaW5jbHVkZWQgdG8gb2ZmZXIgb3RoZXIgYXZlbnVlcyBpbiBkZXRlcm1pbmluZyBhIGdvb2QgbW92aWUsIG91ciAidGVzdHMiIGFyZSBzaW1wbHkgbm90IGVub3VnaC4gV2l0aCB0aGUgbGltaXRlZCBzY29wZSBvZiBhdmFpbGFibGUgYW5kICJwZXJmZWN0IiBkYXRhLCBvdXIgcmVzZWFyY2ggZmFjZSByZWFsIHdvcmxkIGxpbWl0YXRpb25zIHRoYXQgZmFpbCB0byBhc2NlcnRhaW4gdGhlIHNldmVyaXR5IGFuZCBhcnJheSBvZiBIb2xseXdvb2QncyBpbmVxdWFsaXRpZXMgdGhhdCBhcmUgYmV5b25kIHRoZSB3aGl0ZSBtYWxlIHBvcHVsYXRpb24uIEl0IGFsc28gbGVhdmVzIG91dCB0aGUgcG9wdWxhdGlvbiB0aGF0IHN0YW5kcyBiZWhpbmQgdGhlIGNhbWVyYSBpbiBtb3ZpZSBwcm9kdWN0aW9uIHN1Y2ggYXMgc2NyZWVud3JpdGVycywgcHJvZHVjZXJzLCBzZXQgZGVzaWduZXJzLCBldGMuIEFsbCBvZiB0aGVzZSBhcmUsIGhlbmNlLCByZWZsZWN0ZWQgaW4gb3VyIHZpc3VhbGl6YXRpb25zLiBIb3dldmVyLCB3ZSBob3BlIHRoYXQgb3VyIHJlc2VhcmNoIGNhbiBzZXJ2ZSBhcyBhbiBpbmNlbnRpdmUgZm9yIHRoZSBmaWxtIGluZHVzdHJ5IGFzIHdlbGwgYXMgaXRzIGF1ZGllbmNlIHRvIGJlIG1vcmUgY3JpdGljYWwgb2YgbW92aWVzIGFuZCBtb3ZpZSBtYWtpbmcuICAgICAKCgoKIyBDb2RlIEFwcGVuZGl4CgpgYGB7ciwgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3BsaXRzdGFja3NoYXBlKQpsaWJyYXJ5KGRicGx5cikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkoZml2ZXRoaXJ0eWVpZ2h0KQpsaWJyYXJ5KGhpZ2hjaGFydGVyKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShydmVzdCkKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdhcG1pbmRlcikKbGlicmFyeShmb3JjYXRzKQpsaWJyYXJ5KG1hZ3JpdHRyKQoKCiNMb2FkaW5nIHJhdyBkYXRhCmJveF9vZmZpY2UgPC1yZWFkX2NzdigiQWxsIFRpbWUgV29ybGR3aWRlIEJveCBPZmZpY2UuY3N2IikKbW92aWVzX2luZm8gPC0gcmVhZF9jc3YoIm1vdmllcy5jc3YiKQpvc2NhcnNfYXdhcmQgPC0gcmVhZF9jc3YoInRoZV9vc2Nhcl9hd2FyZC5jc3YiKQpiZWNoZGVsIDwtIGRhdGEuZnJhbWUoYmVjaGRlbCkKYmVjaGRlbHNldCA8LSByZWFkX2NzdigiYmVjaGRlbHNldC5jc3YiKQpCZWNoZGVsbW9uZXkgPC0gcmVhZF9jc3YoIkJlY2hkZWxtb25leS5jc3YiKQpiaW9waWNzIDwtIGRhdGEuZnJhbWUoYmlvcGljcykKUmF0aW5nR3Jvc3MgPC0gcmVhZF9jc3YoIlJhdGluZ0dyb3NzX2VkaXQyLmNzdiIpCgpgYGAKCmBgYHtyLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNEYXRhIGNsZWFuaW5nIGZvciBmaWd1cmUgMQojYXZlcmFnZSBncm9zc2luZyBmb3IgZWFjaCB0b3AgMjAgc2NvcmVkCgp0b3Bfc2NvcmUgPC0gbW92aWVzX2luZm8gJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZSwgeWVhciwgZ3Jvc3MpICU+JSAKICBhcnJhbmdlKGRlc2Moc2NvcmUpKQoKI2F2ZXJhZ2UgZ3Jvc3NpbmcgZm9yIGVhY2ggdG9wIDIwIHNjb3JlZAoKbG93X3Njb3JlIDwtIG1vdmllc19pbmZvICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUsIHllYXIsIGdyb3NzKSAlPiUgCiAgYXJyYW5nZShzY29yZSkKCgoKb3NjYXJ3aW5zIDwtICBtb3ZpZXNfaW5mbyAlPiUgCiAgZmlsdGVyKG5hbWUgJWluJSBjKCJUaGUgTG9yZCBvZiB0aGUgUmluZ3M6IFRoZSBSZXR1cm4gb2YgdGhlIEtpbmciLCAiVGl0YW5pYyIsICJCZW4tSHVyIiwgIldlc3QgU2lkZSBTdG9yeSIsICJUaGUgRW5nbGlzaCBQYXRpZW50IiwgIlRoZSBMYXN0IEVtcGVyb3IiLCAiR2lnaSIsICJTbHVtZG9nIE1pbGxpb25haXJlIiwgIkFtYWRldXMiLCAiR2FuZGhpIikpICU+JSAKIHN1bW1hcml6ZShzdW09c3VtKGdyb3NzKSkKCm1vdmllc19pbmZvICU+JQogIGdyb3VwX2J5KHllYXIpICU+JQogIHN1bW1hcml6ZSh0b3RhbF9tb3ZpZXMgPSBuKCksCiAgICAgICAgICAgIGFtZXJpY2FuX21vdmllcyA9IHN1bShjb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIiksCiAgICAgICAgICAgIHBlcmNlbnRfYW1lcmljYW4gPSAxMDAgKiBhbWVyaWNhbl9tb3ZpZXMgLyB0b3RhbF9tb3ZpZXMpCgoKZG91YmxlZGF0YSA8LSBtb3ZpZXNfaW5mbyAlPiUKICBsZWZ0X2pvaW4oUmF0aW5nR3Jvc3MsCiAgICBieSA9IGMoIm5hbWUiLCAieWVhciIgPSAiWWVhciIpKQoKCnRvcGdyb3NzIDwtIGRvdWJsZWRhdGEgJT4lIAogIGZpbHRlcihkb3VibGVkYXRhJFJhbmsgPCAyNSkgJT4lICAKICBhcnJhbmdlKGRlc2MoYFdvcmxkd2lkZUJveCBPZmZpY2VgKSkgJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZS54LCBSYW5rLCBgV29ybGR3aWRlQm94IE9mZmljZWApCgpkdXBsaWNhdGVfcm93cyA8LSB0b3Bncm9zc1tkdXBsaWNhdGVkKHRvcGdyb3NzKSwgXQp0b3Bncm9zcyA8LSB1bmlxdWUodG9wZ3Jvc3MpCgoKdG9wcmF0ZSA8LSBkb3VibGVkYXRhICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgUmFuaywgYFdvcmxkd2lkZUJveCBPZmZpY2VgKSAlPiUgCiAgYXJyYW5nZShkZXNjKHNjb3JlLngpKSAKCiAgICAgCnRvcGdyb3NzXzIwIDwtIGhlYWQodG9wZ3Jvc3MsIG4gPSAyMCkgJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZS54LCBgV29ybGR3aWRlQm94IE9mZmljZWApCnRvcHNjb3JlXzIwIDwtIGhlYWQodG9wcmF0ZSwgbiA9IDIwKSAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLngsIGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkKCgoKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDIKIyBDaGFuZ2luZyBCb3ggT2ZmaWNlIHZhcmlhYmxlcyBpbnRvIG51bWVyaWNhbCB2YWx1ZXMKYm94X29mZmljZSA8LWJveF9vZmZpY2UgJT4lIAogbXV0YXRlKGBXb3JsZHdpZGVCb3ggT2ZmaWNlYD1hcy5udW1lcmljKHN0cl9yZXBsYWNlX2FsbChgV29ybGR3aWRlQm94IE9mZmljZWAsIlskLF0iLCIiKSkpICU+JSAKICBtdXRhdGUoYERvbWVzdGljQm94IE9mZmljZWA9YXMubnVtZXJpYyhzdHJfcmVwbGFjZV9hbGwoYERvbWVzdGljQm94IE9mZmljZWAsIlskLF0iLCIiKSkpICU+JQogIG11dGF0ZShgSW50ZXJuYXRpb25hbEJveCBPZmZpY2VgPWFzLm51bWVyaWMoc3RyX3JlcGxhY2VfYWxsKGBJbnRlcm5hdGlvbmFsQm94IE9mZmljZWAsIlskLF0iLCIiKSkpCgojR2V0dGluZyB0aGUgVG9wIDIwIEJveCBPZmZpY2UKYm94X29mZmljZV90b3AyMCA8LSBib3hfb2ZmaWNlICU+JSAgCiAgYXJyYW5nZShSYW5rKSAlPiUgCiAgaGVhZCgyMCkgJT4lIAogIG11dGF0ZShNb3ZpZT1pZmVsc2UoTW92aWU9PSJIYXJyeSBQb3R0ZXIgYW5kIHRoZSBEZWF0aGx5IEhhbGxvd3M64oCmIiwgIkhhcnJ5IFBvdHRlciBhbmQgdGhlIERlYXRobHkgSGFsbG93czogUGFydCAyIixNb3ZpZSkpCgoKI0NyZWF0aW5nIE9zY2FyIGNhdGVnb3J5IGRhdGEgZnJhbWUKb3NjYXJzX2NhdGVnb3J5IDwtIHRpYmJsZSgKbGV2ZWxzKGZhY3Rvcihvc2NhcnNfYXdhcmQkY2F0ZWdvcnkpKSkKICAKCm9zY2Fyc19jYXRlZ29yeSA8LSBvc2NhcnNfY2F0ZWdvcnkgJT4lIAogIHJlbmFtZSgiY2F0ZWdvcnkiPSJsZXZlbHMoZmFjdG9yKG9zY2Fyc19hd2FyZCRjYXRlZ29yeSkpIikgCiAgCgpvc2NhcnNfY2F0ZWdvcnkgPC0gb3NjYXJzX2NhdGVnb3J5ICU+JSAKICBtdXRhdGUoYnJvYWRfY2F0ZWdvcnk9d29yZChjYXRlZ29yeSwxKSkgJT4lIAogIG11dGF0ZShicm9hZF9jYXRlZ29yeT0KICAgICAgICAgICBjYXNlX3doZW4oYnJvYWRfY2F0ZWdvcnkgPT0iQVJUIiB+IkFSVCBESVJFQ1RJT04iLAogICAgICAgICAgICAgICAgICAgICBicm9hZF9jYXRlZ29yeSA9PSAiQkVTVCIgfiAiQkVTVCBQSUNUVVJFIiwKICAgICAgICAgICAgICAgICAgICAgYnJvYWRfY2F0ZWdvcnkgPT0gIkZJTE0iIH4gIkZJTE0gRURJVElORyIsCiAgICAgICAgICAgICAgICAgICAgIGJyb2FkX2NhdGVnb3J5ID09ICJBQ1RPUiIgfCBicm9hZF9jYXRlZ29yeT09IkFDVFJFU1MiIH4gIkFDVElORyIsCiAgICAgICAgICAgICAgICAgICAgVFJVRSB+IGJyb2FkX2NhdGVnb3J5KQogICAgICAgICAgICApIAoKI1RvcCAyMCBCb3ggT2ZmaWNlIE1vdmllcyBhbmQgYXdhcmRzIGRhdGFzZXQgYnkgam9pbmluZyBkYXRhZnJhbWVzCmJveF9vZmZpY2VfdG9wMjBfYXdhcmRzIDwtIGJveF9vZmZpY2VfdG9wMjAgJT4lIAogIGlubmVyX2pvaW4ob3NjYXJzX2F3YXJkLGJ5PWMoIk1vdmllIj0iZmlsbSIpKSAlPiUgCiAgZmlsdGVyKFllYXIgPT0geWVhcl9maWxtKSAlPiUgCiAgaW5uZXJfam9pbihvc2NhcnNfY2F0ZWdvcnkpICAKCmJveF9vZmZpY2VfdG9wMjBfYXdhcmRzIDwtIGJveF9vZmZpY2VfdG9wMjBfYXdhcmRzICU+JSBncm91cF9ieShNb3ZpZSx5ZWFyX2ZpbG0pICU+JSAKICBzdW1tYXJpemUodG90YWw9bigpKSAlPiUgIGlubmVyX2pvaW4ob3NjYXJzX2F3YXJkLGJ5PWMoIk1vdmllIj0iZmlsbSIpKSAlPiUgCiAgZmlsdGVyKHllYXJfZmlsbS54ID09IHllYXJfZmlsbS55KSAlPiUgCiAgaW5uZXJfam9pbihvc2NhcnNfY2F0ZWdvcnkpICAlPiUgCiAgc2VsZWN0KE1vdmllLCB5ZWFyX2ZpbG0ueCx0b3RhbCx5ZWFyX2NlcmVtb255LG5hbWUsd2lubmVyLGJyb2FkX2NhdGVnb3J5KQpgYGAKCmBgYHtyLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNEYXRhIGNsZWFuaW5nIGZvciBmaWd1cmUgMwojQ2hhbmdpbmcgbW92aWUgbmFtZXMgc28gdGhleSBtYXRjaCBhY3Jvc3MgbW92aWVzX2luZm8gYW5kIGJveF9vZmZpY2VfdG9wMjAKCm1vdmllc19pbmZvIDwtIG1vdmllc19pbmZvICU+JSAgbXV0YXRlKG5hbWU9Y2FzZV93aGVuKAogIG5hbWU9PSJTdGFyIFdhcnM6IEVwaXNvZGUgVklJIC0gVGhlIEZvcmNlIEF3YWtlbnMiIH4gIlN0YXIgV2FycyBFcC4gVklJOiBUaGUgRm9yY2UgQXdha2VucyIsCiAgbmFtZSA9PSJTdGFyIFdhcnM6IEVwaXNvZGUgVklJSSAtIFRoZSBMYXN0IEplZGkiIH4gIlN0YXIgV2FycyBFcC4gVklJSTogVGhlIExhc3QgSmVkaSIsClRSVUV+bmFtZSkpICU+JSAKICBtdXRhdGUoY29tcGFueT1jYXNlX3doZW4oCiAgICBjb21wYW55PT0iV2FsdCBEaXNuZXkgQW5pbWF0aW9uIFN0dWRpb3MiIHwgY29tcGFueT09IldhbHQgRGlzbmV5IFBpY3R1cmVzIiB+IldhbHQgRGlzbmV5IiwKVFJVRX5jb21wYW55KSkKCiNKb2luaW5pbmcgbW92aWVzX2luZm8gYW5kIGJveF9vZmZpY2VfdG9wMjAKCmJveF9vZmZpY2VfdG9wMjBfaW5mbzwtIGJveF9vZmZpY2VfdG9wMjAgJT4lCiAgaW5uZXJfam9pbihtb3ZpZXNfaW5mbyxieT1jKCJNb3ZpZSI9Im5hbWUiLCJZZWFyIj0ieWVhciIpKQoKI01ha2luZyB0b3AyMCBtYWluIGNoYXJhY3RlcidzIHJhY2UgZGF0YSBmcmFtZQp0b3AyMF9yYWNlIDwtIGRhdGEuZnJhbWUoc3Rhcj1ib3hfb2ZmaWNlX3RvcDIwX2luZm8kc3RhcixSYWNlPWMoIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIkJsYWNrIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJCbGFjayIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiKSkKCiNKb2luaW5nIGJveF9vZmZpY2VfdG9wMjBfaW5mbyB3aXRoIHRvcDIwX3JhY2UgZGF0YWZyYW1lCmJveF9vZmZpY2VfdG9wMjBfaW5mbyA8LSBib3hfb2ZmaWNlX3RvcDIwX2luZm8gJT4lIGRhdGEuZnJhbWUodG9wMjBfcmFjZSkgJT4lIHNlbGVjdCghc3Rhci4xKQoKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDQKCmJlY2hkZWxzZXQgPC0gYmVjaGRlbHNldCAlPiUgCiAgbXV0YXRlKHNldF9mYWN0b3IgPSBmYWN0b3Ioc2V0KSkgCgpiZWNoZGVsc2V0YXYgPC0gYmVjaGRlbHNldCAlPiUgCiAgZ3JvdXBfYnkoc2V0X2ZhY3RvciwgY2xlYW5fdGVzdCkgJT4lIAogIHN1bW1hcml6ZShjb3VudCA9IG4gKCkpCgpiZWNoZGVsc2V0YXYgPC0gYmVjaGRlbHNldGF2ICU+JSAKICBtdXRhdGUocGVyY2VudCA9IGNvdW50LyAyMCAqIDEwMCkKCmJlY2hkZWxhdiA8LSBiZWNoZGVsICU+JSAKICBncm91cF9ieShjbGVhbl90ZXN0KSAlPiUgIAogIHN1bW1hcml6ZSAoY291bnQgPSBuICgpKQoKYmVjaGRlbGF2IDwtIGJlY2hkZWxhdiAlPiUgIAogICAgbXV0YXRlKHBlcmNlbnQgPSByb3VuZChjb3VudC8gMTc5NCAqIDEwMCkpICU+JSAKICAgIG11dGF0ZShzZXRfZmFjdG9yID0gIkF2ZXJhZ2UgQmVjaGRlbCBTY29yZXMiKQoKam9pbnRhdiA8LSByYmluZChiZWNoZGVsc2V0YXYsIGJlY2hkZWxhdikgCgoKam9pbnRhdiRjbGVhbl90ZXN0IDwtIGZhY3Rvcihqb2ludGF2JGNsZWFuX3Rlc3QsIGxldmVscyA9IGMoIm5vd29tZW4iLCAibm90YWxrIiwgIm1lbiIsICJkdWJpb3VzIiwgIm9rIikpCgpgYGAKCmBgYHtyLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsZmlnLmFsdD0iQSBzY2F0dGVyIHBsb3Qgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIElNRGIgc2NvcmUgYW5kIHdvcmxkd2lkZSBib3ggb2ZmaWNlIGdyb3NzIGZvciBtb3ZpZXMgd2l0aCBkaWZmZXJlbnQgQmVjaGRlbCB0ZXN0IHNjb3Jlcy4gRWFjaCBwb2ludCByZXByZXNlbnRzIGEgbW92aWUgYW5kIGlzIGNvbG9yZWQgYmFzZWQgb24gaXRzIEJlY2hkZWwgdGVzdCBzY29yZS4gVGhlIGxlZ2VuZCBzaG93cyB0aGUgZml2ZSBCZWNoZGVsIHRlc3Qgc2NvcmVzOiBubyB3b21lbiwgbm8gdGFsaywgbWVuLCBkdWJpb3VzLCBhbmQgb2suIFRoZSB4LWF4aXMgcmVwcmVzZW50cyB0aGUgSU1EYiBzY29yZSwgYW5kIHRoZSB5LWF4aXMgcmVwcmVzZW50cyB0aGUgd29ybGR3aWRlIGJveCBvZmZpY2UgZ3Jvc3MgaW4gbWlsbGlvbnMvIGJpbGxpb25zIG9mIGRvbGxhcnMuIFRoZSB0b29sdGlwIGRpc3BsYXlzIHRoZSBtb3ZpZSBuYW1lLCBJTURiIHNjb3JlLCBhbmQgd29ybGR3aWRlIGdyb3NzaW5nIGZvciBlYWNoIHBvaW50LiJ9CiNGaWd1cmUgMQpjb2xvcnMgPC0gYygiI0FDMjUyOCIsICIjRTQ3OTJDIiwgIiM3NjQ0ODQiLCAiIzM0NjQ5MSIsICIjNDQ4NzQ2IikKCmZpZzE8LXBsb3RfbHkoYmVjaGRlbHNldCwgeCA9IH5zY29yZS54LCB5ID0gfmBXb3JsZHdpZGVCb3ggT2ZmaWNlYCwgY29sb3IgPSB+Y2xlYW5fdGVzdCwgY29sb3JzID0gY29sb3JzLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ21hcmtlcnMnLAogIGhvdmVyaW5mbyA9ICd0ZXh0JywKICB0ZXh0ID0gfnBhc3RlKCc8L2JyPicsIG5hbWUsIAogICAgICAgICAgICAgICAgJzwvYnI+JywgIklNREIgU2NvcmU6Iiwgc2NvcmUueCwgCiAgICAgICAgICAgICAgICAnPC9icj4nLCAiV29ybGR3aWRlIEdyb3NzaW5nOiIsIGNvbW1hKGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkpKSAlPiUgCiAgbGF5b3V0KHRpdGxlID0gJ0lNREIgU2NvcmUgdnMuIEFtb3VudCBvZiBNb25leSBHcm9zc2VkJywgCiAgICAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICdJTURCIFNjb3JlJyksIAogICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnV29ybGR3aWRlIEJveCBPZmZpY2UnKSwgCiAgICAgICAgICAgbGVnZW5kID0gbGlzdCh0aXRsZSA9IGxpc3QodGV4dCA9ICJCZWNoZGVsIFRlc3QgU2NvcmUiKSwKICAgICAgICAgICAgICAgICAgICAgICB0aXRsZXMgPSBsaXN0KHRvcGdyb3NzXzIwID0gIlRvcCAyMCBHcm9zc2luZyIsIHRvcHNjb3JlXzIwID0gIlRvcCAyMCBTY29yZWQiKSkpCgoKCgpgYGAKCgpgYGB7cixmaWcud2lkdGg9MTAsZmlnLmhlaWdodD02LGZpZy5hbHQ9IlRoaXMgYmFyIGdyYXBoIHNob3dzIHRoZSB0b3RhbCBudW1iZXIgb2Ygb3NjYXIgYXdhcmRzIG5vbWluYXRpb25zIG9mIHRoZSB0b3AgMjAgbW92aWVzIHdpdGggdGhlIGhpZ2hlc3QgV29ybGR3aWRlIEJveCBPZmZpY2UgYnkgQ2F0ZWdvcnkgYW5kIFdpbnMiLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNGaWd1cmUgMgoKZmlnMjwtYm94X29mZmljZV90b3AyMF9hd2FyZHMgJT4lIAogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKE1vdmllLCB0b3RhbCwuZnVuPXN1bSksYWxwaGE9d2lubmVyLGZpbGw9ZmN0X3Jlb3JkZXIoYnJvYWRfY2F0ZWdvcnksd2lubmVyKSkpICsgCiAgZ2VvbV9iYXIoKSsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkrCiAgY29vcmRfZmxpcCgpKwogIGxhYnMoeT0iVG90YWwgTm9taW5hdGlvbnMiLHg9Ik1vdmllIix0aXRsZT0iVG9wIDIwIE1vdmllcyB3aXRoIEhpZ2hlc3QgV29ybGR3aWRlIEJveCBPZmZpY2UgdnMgT3NjYXJzIEF3YXJkcyIsc3VidGl0bGUgPSAiQnkgQ2F0ZWdvcnkgYW5kIFdpbnMiLGZpbGw9IkNhdGVnb3J5IixhbHBoYT0iV2lubmVyIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkIixzaXplPTE2KSxwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSxheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCgoKYGBgCgoKYGBge3IsZmlnLndpZHRoPTYsZmlnLmhlaWdodD00LGZpZy5hbHQ9IlRoaXMgc2NhdHRlciBwbG90IGRpc3BsYXlzIHRoZSB0b3AgMjAgaGlnaGVzdCBncm9zc2luZyBtb3ZpZXMgb2YgYWxsIHRpbWUgYnkgdGhlaXIgcHJvZml0IGFuZCB0aGUgbWFpbiBjaGFyYWN0ZXIncyByYWNlLiBJdCBzaG93cyB0aGF0IG91dCBvZiAyMCBtb3ZpZXMsIDIgaGFzIGEgbm9uLXdoaXRlIG1haW4gY2hhcmFjdGVyLiIsZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0ZpZ3VyZSAzCmZpZzM8LWJveF9vZmZpY2VfdG9wMjBfaW5mbyAlPiUgCiAgbXV0YXRlKFByb2ZpdD1ncm9zcy1idWRnZXQpICU+JQogIGdncGxvdChhZXMoeD1idWRnZXQseT1ncm9zcyxjb2xvcj1SYWNlLHNpemU9UHJvZml0KSkgKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX2NvbW1hKCkpKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9jb21tYSgpKSsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfY29tbWEoKSkrCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbj0iRSIpKwogIGxhYnMoeT0iVG90YWwgR3Jvc3MiLHg9IkJ1ZGdldCIsdGl0bGU9IlRvcCAyMCBNb3ZpZXMgd2l0aCBIaWdoZXN0IFdvcmxkd2lkZSBCb3ggT2ZmaWNlIixzdWJ0aXRsZSA9ICJCeSBQcm9maXQgYW5kIFJhY2Ugb2YgTWFpbiBDaGFyYWN0ZXIiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiLHNpemU9MTIpLHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT04KSkrCiAgYW5ub3RhdGUoInRleHQiLHg9MjAwMDAwMDAwLHk9MTQzMDAwMDAwMCxsYWJlbD0iQmxhY2sgUGFudGhlciIsc2l6ZT0zLGNvbG9yPSJyZWQzIikrCiAgIGFubm90YXRlKCJ0ZXh0Iix4PTI2MDAwMDAwMCx5PTE3NTAwMDAwMDAsbGFiZWw9IlRoZSBMaW9uIEtpbmcgKDIwMTkpIixzaXplPTMsY29sb3I9InJlZDMiKQoKICAKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbHQ9IkEgc3RhY2tlZCBjb2x1bW4gY2hhcnQgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBkaXN0cmlidXRpb24gb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0IGJ5IGRpZmZlcmVudCBtb3ZpZSBzZXRzLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIG1vdmllIHNldHMsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0LiBUaGUgY2hhcnQgaXMgZGl2aWRlZCBpbnRvIGZpdmUgY2F0ZWdvcmllcyBiYXNlZCBvbiB0aGUgQmVjaGRlbCB0ZXN0IHNjb3JlOiBubyB3b21lbiwgbm8gdGFsaywgbWVuLCBkdWJpb3VzLCBhbmQgb2suIFRoZSB0b29sdGlwIHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIG1vdmllcyBmb3IgZWFjaCBjYXRlZ29yeSBhbmQgbW92aWUgc2V0LiJ9CiNGaWd1cmUgNAoKCmZpZzQ8LWhjaGFydChqb2ludGF2LCAiY29sdW1uIiwgaGNhZXMoeCA9IHNldF9mYWN0b3IsIHkgPSBjb3VudCwgZ3JvdXAgPSBjbGVhbl90ZXN0KSwgc3RhY2tpbmcgPSAicGVyY2VudCIpICU+JSAKICBoY190aXRsZSh0ZXh0ID0gIkJlY2hkZWwgVGVzdCBTY29yZXMiKSAlPiUgCiAgaGNfY29sb3JzKGNvbG9ycykgJT4lIAogIGhjX3Rvb2x0aXAocG9pbnRGb3JtYXQgPSAie3Nlcmllcy5uYW1lfToge3BvaW50LnBlcmNlbnRhZ2U6LjFmfSUiKSAlPiUgCiAgaGNfeUF4aXModGl0bGUgPSAiUGVyY2VudGFnZSIsIGxhYmVscyA9IGxpc3QoZm9ybWF0ID0gJ3t2YWx1ZX0lJykpICU+JQogIGhjX3hBeGlzKHRpdGxlID0gTlVMTCkgJT4lIAogIGhjX2NvbG9ycyhjb2xvcnMpICU+JSAKICBoY19sZWdlbmQoZW5hYmxlZCA9IFRSVUUpCmBgYAoKCiMgT3RoZXIgU291cmNlcwoKQnJ1ZWdnZW1hbm4sIFRvbS4g4oCcVGhlYXRlciBBdWRpZW5jZXMgU2hyYW5rIGJ5IEhhbGYgaW4gdGhlIExhc3QgNCBZZWFycy4gQ2FuIE1vdmllcyBHZXQgVGhlbSBCYWNrP+KAnSBJTURiLCA1IEphbnVhcnkgMjAyMywgaHR0cHM6Ly93d3cuaW1kYi5jb20vbmV3cy9uaTYzODk5NDA4LiBBY2Nlc3NlZCAzIE1heSAyMDIzLgo8YnI+CkhpY2tleSwgV2FsdCwgZXQgYWwuIENyZWF0aW5nIFRoZSBOZXh0IEJlY2hkZWwgVGVzdCB8IEZpdmVUaGlydHlFaWdodCwgMjEgRGVjZW1iZXIgMjAxNywgaHR0cHM6Ly9wcm9qZWN0cy5maXZldGhpcnR5ZWlnaHQuY29tL25leHQtYmVjaGRlbC8uIEFjY2Vzc2VkIDMgTWF5IDIwMjMuCjxicj4K4oCcSU1EYi7igJ0gV2lraXBlZGlhLCBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JTURiLiBBY2Nlc3NlZCAzIE1heSAyMDIzLgo8YnI+ClJleW5vbGRzLCBNYXR0LiDigJxZb3Ugc2hvdWxkIGlnbm9yZSBmaWxtIHJhdGluZ3Mgb24gSU1EYiBhbmQgUm90dGVuIFRvbWF0b2VzLuKAnSBXaXJlZCBVSywgMjQgT2N0b2JlciAyMDE3LCBodHRwczovL3d3dy53aXJlZC5jby51ay9hcnRpY2xlL3doaWNoLWZpbG0tcmFua2luZy1zaXRlLXNob3VsZC1pLXRydXN0LXJvdHRlbi10b21hdG9lcy1pbWRiLW1ldGFjcml0aWMuIEFjY2Vzc2VkIDMgTWF5IDIwMjMuCjxicj4KVWd3dSwgUmVnZ2llLiDigJxUaGUgSGFzaHRhZyBUaGF0IENoYW5nZWQgdGhlIE9zY2FyczogQW4gT3JhbCBIaXN0b3J5IChQdWJsaXNoZWQgMjAyMCku4oCdIFRoZSBOZXcgWW9yayBUaW1lcywgOSBTZXB0ZW1iZXIgMjAyMCwgaHR0cHM6Ly93d3cubnl0aW1lcy5jb20vMjAyMC8wMi8wNi9tb3ZpZXMvb3NjYXJzc293aGl0ZS1oaXN0b3J5Lmh0bWwuIEFjY2Vzc2VkIDMgTWF5IDIwMjMuCjxicj4KV2F0a2lucywgQWxiZXJ0LiDigJxSYWNlIGFuZCBldGhuaWNpdHkgaW4gdGhlIFVuaXRlZCBTdGF0ZXMu4oCdIFdpa2lwZWRpYSwgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUmFjZV9hbmRfZXRobmljaXR5X2luX3RoZV9Vbml0ZWRfU3RhdGVzLiBBY2Nlc3NlZCAzIE1heSAyMDIzLg==